So I recently learned of the new JavaCompiler API available in JDK 1.6. This makes it very simple to compile a String
to a .class
file directly from running code:
String className = "Foo";
String sourceCode = "...";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>()
{{
add(new JavaSourceFromString(className, sourceCode));
}};
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);
return bos.toByteArray();
You can grab the source to JavaSourceFromString
from the Javadoc.
This will very handily compile sourceCode
to Foo.class
in the current working directory.
My question is: is it possible to compile straight to a byte[]
array, and avoid the messiness of dealing with File
I/O altogether?
Maybe you could create your own javax.tools.JavaFileManager
implementing class where you would return your own implementation of javax.tools.FileObject
which would then write it out to memory instead to disk. So for your subclass of javax.tools.FileObject
Writer openWriter() throws IOException
method you would return a java.io.StringWriter
. All the methods should be converted to their String
counterparts.
The reason that there is no standard API to write bytecodes to a byte array is that compiling a single Java source file may result in multiple bytecode files. For example, any source file with nested / inner / anonymous classes will result in multiple bytecode files.
If you roll your own JavaFileManager, you will need to deal with this situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With