Skip to content

Commit bca1b6e

Browse files
Copilotsimbo1905
andauthored
Issue #0 refine jdt2jar packaging
Agent-Logs-Url: https://github.com/simbo1905/java.util.json.Java21/sessions/46541410-0395-47ca-bf41-41ba6d0a8dc6 Co-authored-by: simbo1905 <322608+simbo1905@users.noreply.github.com>
1 parent dfc8f52 commit bca1b6e

2 files changed

Lines changed: 50 additions & 51 deletions

File tree

jdt2jar/src/main/java/json/java21/jdt2jar/Jdt2Jar.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import java.io.ByteArrayOutputStream;
77
import java.io.IOException;
8-
import java.io.InputStream;
98
import java.io.UncheckedIOException;
109
import java.nio.charset.StandardCharsets;
1110
import java.nio.file.Files;
@@ -63,15 +62,15 @@ int execute(String[] args) throws IOException {
6362

6463
final var schemaJson = Files.readString(options.schemaPath());
6564
final var schema = Json.parse(schemaJson);
66-
final var generated = JtdCodegen.compileWithStats(schema, options.packageName(), options.className());
65+
final var generatedBytes = JtdCodegen.compileBytes(schema, options.packageName(), options.className());
6766

6867
if (options.runtime() != DEFAULT_RUNTIME) {
6968
throw new UsageException("Unsupported runtime version: " + options.runtime()
7069
+ " (only 21 is currently emitted)");
7170
}
7271

7372
final var output = options.output() != null ? options.output() : defaultOutput(options.schemaPath());
74-
writeValidatorJar(output, options, schemaJson, generated.classBytes());
73+
writeValidatorJar(output, options, schemaJson, generatedBytes);
7574

7675
if (options.includeSources()) {
7776
writeSourceFile(sourcePathFor(output), options);
@@ -151,7 +150,7 @@ private static void copyJarEntries(JarOutputStream out, Set<String> written, Pat
151150
continue;
152151
}
153152
try (final var in = jar.getInputStream(entry)) {
154-
writeEntry(out, written, name, readAllBytes(in));
153+
writeEntry(out, written, name, in.readAllBytes());
155154
}
156155
}
157156
}
@@ -304,10 +303,6 @@ private static String toQualifiedName(String packageName, String className) {
304303
return packageName + "." + className;
305304
}
306305

307-
private static byte[] readAllBytes(InputStream in) throws IOException {
308-
return in.readAllBytes();
309-
}
310-
311306
private static void printUsage() {
312307
System.out.println("""
313308
jdt2jar <schema.json> [options]

json-java21-jtd-codegen/src/main/java/json/java21/jtd/codegen/JtdCodegen.java

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,62 @@ public final class JtdCodegen {
2222

2323
static final Logger LOG = Logger.getLogger(JtdCodegen.class.getName());
2424
private static final AtomicLong COUNTER = new AtomicLong();
25+
private static final String DEFAULT_PACKAGE = "json.java21.jtd.codegen";
2526

2627
private JtdCodegen() {}
2728

2829
/// Result of compilation including the validator and generated class statistics.
29-
public record CompileResult(JtdValidator validator, int classfileBytes, byte[] classBytes) {}
30+
public record CompileResult(JtdValidator validator, int classfileBytes, byte[] classBytes) {}
3031

31-
/// Public factory invoked by [JtdValidator.compileGenerated] via reflection.
32-
public static JtdValidator compile(JsonValue schema) {
33-
return compileWithStats(schema).validator();
34-
}
32+
/// Public factory invoked by [JtdValidator.compileGenerated] via reflection.
33+
public static JtdValidator compile(JsonValue schema) {
34+
return compileWithStats(schema).validator();
35+
}
3536

36-
/// Compiles the schema and returns both the validator and the generated
37-
/// classfile size in bytes. Useful for benchmarking and diagnostics.
38-
public static CompileResult compileWithStats(JsonValue schema) {
39-
return compileWithStats(schema, "json.java21.jtd.codegen", "Generated_" + COUNTER.incrementAndGet());
40-
}
37+
/// Compiles the schema and returns both the validator and the generated
38+
/// classfile size in bytes. Useful for benchmarking and diagnostics.
39+
public static CompileResult compileWithStats(JsonValue schema) {
40+
final var className = "Generated_" + COUNTER.incrementAndGet();
41+
final var bytes = buildBytes(schema, DEFAULT_PACKAGE, className);
42+
return instantiate(schema, bytes, DEFAULT_PACKAGE, className);
43+
}
44+
45+
/// Compiles the schema into a named validator class and returns the raw bytes.
46+
///
47+
/// @param schema the JTD schema as a parsed [JsonValue]
48+
/// @param packageName Java package for the generated validator
49+
/// @param className Generated validator class name
50+
/// @return the generated class bytes
51+
public static byte[] compileBytes(JsonValue schema, String packageName, String className) {
52+
return buildBytes(schema, packageName, className).clone();
53+
}
4154

42-
/// Compiles the schema into a named validator class.
43-
///
44-
/// @param schema the JTD schema as a parsed [JsonValue]
45-
/// @param packageName Java package for the generated validator
46-
/// @param className Generated validator class name
47-
/// @return the validator, classfile size, and generated bytes
48-
public static CompileResult compileWithStats(JsonValue schema, String packageName, String className) {
49-
final var jtd = new Jtd();
50-
final var compiled = jtd.compileToSchema(schema);
51-
final var schemaJson = schema.toString();
55+
private static CompileResult instantiate(JsonValue schema, byte[] bytes, String packageName, String className) {
56+
final var internalName = packageName.replace('.', '/') + "/" + className;
57+
final var schemaJson = schema.toString();
58+
try {
59+
final var lookup = MethodHandles.lookup();
60+
final var clazz = lookup.defineClass(bytes);
61+
final var ctor = clazz.getConstructor(String.class);
62+
final var validator = (JtdValidator) ctor.newInstance(schemaJson);
63+
return new CompileResult(validator, bytes.length, bytes.clone());
64+
} catch (Exception e) {
65+
throw new RuntimeException("Failed to load generated validator: " + internalName, e);
66+
}
67+
}
5268

53-
final var internalName = packageName.replace('.', '/') + "/" + className;
54-
final var classDesc = ClassDesc.ofInternalName(internalName);
69+
private static byte[] buildBytes(JsonValue schema, String packageName, String className) {
70+
final var jtd = new Jtd();
71+
final var compiled = jtd.compileToSchema(schema);
72+
final var internalName = packageName.replace('.', '/') + "/" + className;
73+
final var classDesc = ClassDesc.ofInternalName(internalName);
5574

56-
LOG.fine(() -> "Generating validator class: " + internalName);
75+
LOG.fine(() -> "Generating validator class: " + internalName);
5776

58-
final var bytes = ClassFile.of().build(classDesc, clb -> {
59-
clb.withVersion(ClassFile.JAVA_21_VERSION, 0);
60-
clb.withFlags(ClassFile.ACC_PUBLIC | ClassFile.ACC_FINAL);
61-
clb.withSuperclass(Descriptors.CD_Object);
77+
return ClassFile.of().build(classDesc, clb -> {
78+
clb.withVersion(ClassFile.JAVA_21_VERSION, 0);
79+
clb.withFlags(ClassFile.ACC_PUBLIC | ClassFile.ACC_FINAL);
80+
clb.withSuperclass(Descriptors.CD_Object);
6281
clb.withInterfaceSymbols(Descriptors.CD_JtdValidator);
6382
clb.with(SourceFileAttribute.of("JtdCodegen"));
6483

@@ -69,20 +88,5 @@ public static CompileResult compileWithStats(JsonValue schema, String packageNam
6988
EmitScaffold.emitToString(clb, classDesc);
7089
EmitScaffold.emitValidateMethod(clb, classDesc, compiled);
7190
});
72-
73-
final JtdValidator validator;
74-
if ("json.java21.jtd.codegen".equals(packageName)) {
75-
try {
76-
final var lookup = MethodHandles.lookup();
77-
final var clazz = lookup.defineClass(bytes);
78-
final var ctor = clazz.getConstructor(String.class);
79-
validator = (JtdValidator) ctor.newInstance(schemaJson);
80-
} catch (Exception e) {
81-
throw new RuntimeException("Failed to load generated validator: " + internalName, e);
82-
}
83-
} else {
84-
validator = JtdValidator.compile(schema);
85-
}
86-
return new CompileResult(validator, bytes.length, bytes.clone());
87-
}
91+
}
8892
}

0 commit comments

Comments
 (0)