Java 1.6 introduced standard Java Compiler API. This API resides in javax.tools package. Using this API we are able to compile Java source. Well that's a good thing for IDE writers as they have a standard API now. That means they don't have to use undocumented classes in com.sun.tools.* packages from jdk/lib/tools.jar library to invoke the compiler. But there's more to it, now developers and framework engineers can generate code during runtime (or java source can be retrieved from other location, may be from database or over the network), compile it using this API and then load it using a custom class loader. Let's see that step by step.
Compiling Java Source from File
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int result = compiler.run(null, null, null,
new File("test-sources/Test.java").getAbsolutePath());
if(result==0){
System.out.println("compilation done");
}
The interface JavaCompiler is the most important interface in this API. ToolProvider.getSystemJavaCompiler() returns the default instance of the interface.
To customize the default behavior we have to get the instance of StandardJavaFileManager which takes care of loading source files, wrapping them in JavaFileObject (File abstraction for Java source and class files) .
Here's a quick view of the javax.tools package.
Interfaces:
Classes:
Example Project
This example has tree main classes:
- CompilingFromFile.java: shows the basic use of
JavaCompiler to compile the java source. On running you will see that the source file test-sources/Test.java will be compiled in the same folder as Test.class.
- FileManagerExample.java: shows how to use
StandardJavaFileManager and to collect compilation warnings/errors using DiagnosticCollector . Also notice how we submitted JavaCompiler.CompilationTask to the java.util.concurrent.Executors task, that's because CompilationTask extends java.util.concurrent.Callable .
- FileManagerExample2.java: shows how to use a customized
DiagnosticListener .
Dependencies and Technologies Used:
|