Summary
There is a considerable amount of subclasses in various codebases of SimpleJavaFileObject, that implement input source files for a compilation. The proposal here is to add a factory to create such a simple input JavaFileObject.
Problem
Around various codebases, there are many subtypes of SimpleJavaFileObject like:
private static class JavaSource extends SimpleJavaFileObject {
private String code;
public JavaSource(String code) {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
This duplication of code seems unnecessary.
Solution
The proposal herein is to create a factory method that would create a subtype of SimpleJavaFileObject similar to the above, based on the provided URI and source code content.
Specification
The proposed addition, including API specification is:
diff --git a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
index a619cf34c9a..1e959133ff3 100644
--- a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
+++ b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
@@ -223,4 +223,48 @@ public boolean isNameCompatible(String simpleName, Kind kind) {
public String toString() {
return getClass().getName() + "[" + toUri() + "]";
}
+
+ /**
+ * Creates a {@link JavaFileObject} which represents the given source content.
+ *
+ * <p>The provided {@code uri} will be returned from {@link #toUri()}.
+ * The provided {@code content} will be returned from {@link #getCharContent(boolean)}.
+ * The {@link #getKind()} method will return {@link Kind#SOURCE}.
+ *
+ * <p>All other methods will behave as described in the documentation in this class,
+ * as if the constructor is called with {@code uri} and {@code Kind.SOURCE}.
+ *
+ * <p>This method can be, for example, used to compile an in-memory String
+ * to a set of classfile in a target directory:
+ * {@snippet lang="java":
+ * var code = """
+ * public class CompiledCode {}
+ * """;
+ * var compiler = ToolProvider.getSystemJavaCompiler();
+ * var targetDirectory = "...";
+ * var task = compiler.getTask(null,
+ * null,
+ * null,
+ * List.of("-d", targetDirectory),
+ * null,
+ * List.of(SimpleJavaFileObject.forSource(URI.create("CompiledCode.java"), code)));
+ * if (!task.call()) {
+ * throw new IllegalStateException("Compilation failed!");
+ * }
+ * }
+ *
+ * @param uri that should be used for the resulting {@code JavaFileObject}
+ * @param content the content of the {@code JavaFileObject}
+ * @return a {@code JavaFileObject} representing the given source content.
+ * @since 23
+ */
+ public static JavaFileObject forSource(URI uri, String content) {
+ return new SimpleJavaFileObject(uri, Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return content;
+ }
+ };
+ }
+
}
- csr of
-
JDK-8325362 Allow to create a simple in-memory input JavaFileObject
-
- Resolved
-