Java SE 6 Compiler API
Now that Java SE is released I wanted to cover one of my favorite feature, the Compiler API. I already wrote about a cool hack that can be done in previous versions of the JDK to compile Java code at runtime. I also wrote about compiling Groovy at runtime. Now I will cover how to compile Java code using the new Compiler API introduced in the JDK SE 6. Please not that the following code use classes that are currently only available with the JDK, not the JRE.
To get started you will need to instantiate a Java Compiler and Java File Manger.
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null);
The next step is to create a compilation task to the Java Compiler. You can add as many task to the Java compiler as you may need. Also note that the getJavaFileObjects method accepts a variable number of arguments so you could pass in as many files as you may need. Also, don’t forget to close the Java File Manager when you are done with it.
File javaFile = new File(“c:/src/com/juixe/Entity.java”);
// getJavaFileObjects’ param is a vararg
Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);
jc.getTask(null, sjfm, null, null, null, fileObjects).call();
// Add more compilation tasks
sjfm.close();
At this point with the above code, if there are no errors the class files would compile to c:/src. If you want to output the class files in a different location you can add options to the compilation task with code similar to the following.
String[] options = new String[]{“-d”, “c:/bin”};
jc.getTask(null, sjfm, null, Arrays.asList(options), null, fileObjects).call();
Once you have compiled the Java source file using the new Java Compiler API, you may want to load the class into your running system. To load a Java class compiled using the Compiler API you can use code similar to that used to load a class compiled using embedded Groovy. Here is how you can load a newly compiled class at runtime.
File outputDir = new File(“c:/bin”);
URL[] urls = new URL[]{outputDir.toURL()};
URLClassLoader ucl = new URLClassLoader(urls, cl);
Class clazz = ucl.loadClass(“com.juixe.Entity”);
Technorati Tags: groovy, java, compiler api, java se, jdk, java 6, mustang, compilation, compile, classloader
Related posts:
August 23rd, 2007 at 9:40 am
Great post!!
I’m trying to get it working but I’m getting NullPointerException when I try to get a handle to the Java compiler.
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
Any ideas why that might be happening?
Thanks
August 23rd, 2007 at 9:46 am
Never mind, I figured it out. Wrong Java 6 inside eclipse. :)
November 10th, 2007 at 12:28 pm
[...] Check the following resources: The Java Compiler API Juixe TechKnow ? Java SE 6 Compiler API [...]
November 30th, 2007 at 5:21 am
[Advert warning - I am the author]
People may also be interested in the wrapper code available at:
http://www-systems.cs.st-andrews.ac.uk/wiki/Dynamic_Java_Compiler
Its aim is the same as the new facilities in Java 6, but has been around for much longer. I think the API is a bit simpler, but you can make up your own mind on that…
December 16th, 2010 at 12:52 am
[...] a piece of Java source code from another running Java program. After a search on the Internet (Juixe) it appeared that within Java all this is a piece of cake. As an example, the following picture [...]