Steps :
- Construct JavaFileObject from any source (i.e, here, from sourceCode String) and make it to iterable object
- Get the Java System Compiler
- Create a compiler task using Compiler.getTask(), (if required create the task with diagnostic collection to get compilation errors)
- Execute the Compiler Task (compile it).
Source Code :
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class CompileDynamicClasses {
static String sourceCode = "class DynamicClass{" + "public static void main (String args[]){"
+ "System.out.println (\"Hello, Dynamic Class!\");" + "}" + "}";
public static void main(String[] args) {
// Construct a JavaFileObject from source code
SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject("DynamicClass",
sourceCode);
// Pack into Iterable compilationunits
JavaFileObject javaFileObjects[] = new JavaFileObject[] { fileObject };
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
/*
* // Construct compiler options, if needed String[] compileOptions =
* new String[] { "-d", "bin" }; Iterable<String> compilationOptionss =
* Arrays.asList(compileOptions);
*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// Use StandardJavaFileManager to customize how a compiler reads and
// writes to files.
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
// DiagnosticCollector used to collect compilation problems
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
/*
* // With Compiler options CompilationTask compilerTask =
* compiler.getTask(null, stdFileManager, diagnostics,
* compilationOptionss, null, compilationUnits);
*/
CompilationTask compilerTask = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
boolean status = compilerTask.call();
if (!status) {// If compilation error occurs
/* Iterate through each compilation problem and print it */
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
}
}
try {
stdFileManager.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Successfully Compiled!...");
}
}
/**
* Creates a dynamic source code file object
*/
class DynamicJavaSourceCodeObject extends SimpleJavaFileObject {
private String qualifiedName;
private String sourceCode;
/**
* Converts the name to an URI, as that is the format expected by
* JavaFileObject
*/
protected DynamicJavaSourceCodeObject(String name, String code) {
super(URI.create("string:///" + name.replaceAll("\\.", "/") + Kind.SOURCE.extension), Kind.SOURCE);
this.qualifiedName = name;
this.sourceCode = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return sourceCode;
}
public String getQualifiedName() {
return qualifiedName;
}
public void setQualifiedName(String qualifiedName) {
this.qualifiedName = qualifiedName;
}
public String getSourceCode() {
return sourceCode;
}
public void setSourceCode(String sourceCode) {
this.sourceCode = sourceCode;
}
}
Reblogged this on Sutoprise Avenue, A SutoCom Source.
nice example, but put the source code inside the “sourcecode” tag, for proper formatting and reading, more here http://goo.gl/WjV7
Thanks, I already put that into “code” tag, but my theme doesn’t support proper code formatting. Let me fix this soon.