Thursday, September 08, 2005

Programmatically compiling Java in JDK 6

Build 47 (August 12th) of JDK 6 (Mustang) includes this improvement:

Category ID Synopsis
java:compiler 
  4164450 JSR 199: Standard interface for Java compilers

(Offhand, why is SUN's HTML for this page so bad? The source HTML is not even valid, let alone tasteful.)

The link is to this bug report; its heart:

This feature is for a standard interface that is available as a standard extension to Java. That way you have a richer way to access the compiler (if one is available) without forking a new process or relying on undocumented features. You also make it easy for the user to install a different compiler without breaking the tools that rely on it.

The Yahoo! group to discuss the feature makes it clear that this feature was originally intended for JDK 5 (Tiger) but pushed back to JDK 6 (Mustang), and that is as far as the group got. However, JDK 5 did expose com.sun.tools.javac.Main. However, the bug report says that JDK 6 addresses:

  • Programmatic API to invoke the compiler
  • API to access structured diagnostic information
  • API to override how the compiler reads and writes source and class files.

Progress!

The JDK 6 API docs do not show any obvious signs of this. So of to the sources (NB — this is the JRL download, not the SCSL). Comparing the two sources for com.sun.tools.javac.Main shows interesting changes. After building the javadocs for just this class, I can read some eye-catching improvements; the opening lines:

The programmatic interface for the Java Programming Language compiler, javac.

Except for the two methods compile(java.lang.String[]) compile(java.lang.String[],java.io.PrintWriter), nothing described in this source file is part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.

Some heavy caveats, but very promising! The documentation for main(java.lang.String[]) is amusing:

Unsupported command line interface.

The full method javadocs for this class are (after cleaning javadocs' peculiar HTML):

main

public static void main(java.lang.String[] args)
                 throws java.lang.Exception

Unsupported command line interface.

Parameters:
args - The command line parameters.
Throws:
java.lang.Exception

compile

public static int compile(java.lang.String[] args)

Programmatic interface to the Java Programming Language compiler, javac.

Parameters:
args - The command line arguments that would normally be passed to the javac program as described in the man page.
Returns:
an integer equivalent to the exit value from invoking javac, see the man page for details.

compile

public static int compile(java.lang.String[] args,
                          java.io.PrintWriter out)

Programmatic interface to the Java Programming Language compiler, javac.

Parameters:
args - The command line arguments that would normally be passed to the javac program as described in the man page.
out - PrintWriter to which the compiler's diagnostic output is directed.
Returns:
an integer equivalent to the exit value from invoking javac, see the man page for details.

Well, it's a start.

3 comments:

Anonymous said...

They should move it to a sane namespace, if it's going to be an official API.

javax.pony.javac

for example.

cheers,
dalibor topic

Anonymous said...

Well I've been waiting a long time for this! You wouldn't believe the hoops I've had to go through to run javac since JDK1.3. Back in those days you had to use some comlicated threading nonsense to get the javac output back into your main process.

Anonymous said...

You're referring to JSR 199 which adds the package javax.tools. Se my blog
on JSR 199 for more info.

com.sun.tools.javac.Main has nothing to do with JSR 199.