org.apache.xml.utils.synthetic
Class JavaUtils

java.lang.Object
  extended byorg.apache.xml.utils.synthetic.JavaUtils

public class JavaUtils
extends Object

This class supports invoking Java compilation from within a Java program. Recent versions of the Java environment have provided such an API (in tools.jar). But that isn't available on all platforms, and a fallback to the command line may be needed (though this too may not always be available, eg. for security reasons).

There's an additional complication in some environments -- such as Microsoft's VJ++ -- where the classpath as seen in the System Properties may not be the one the user expects. The code here is parameterized to try to deal with that.


Field Summary
private static boolean cantLoadCompiler
           
private static boolean debug
           
 
Constructor Summary
JavaUtils()
           
 
Method Summary
static boolean JDKcompile(String fileName, String classPath)
          Try to compile a .java file on disk.
static void setDebug(boolean newDebug)
          Control whether compilation occurs with the -g option (debugging information included in generated classfile).
(package private) static int waitHardFor(Process p)
          Subroutine: Like p.waitFor, but discards the InterruptedException and goes right back into a wait.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cantLoadCompiler

private static boolean cantLoadCompiler

debug

private static boolean debug
Constructor Detail

JavaUtils

public JavaUtils()
Method Detail

setDebug

public static void setDebug(boolean newDebug)
Control whether compilation occurs with the -g option (debugging information included in generated classfile). This is an attribute, rather than a parameter on the compile method, largely because it tends to be an all-or-nothing decision; generally you're either doing program development and want it, or running in production mode and don't. But that may not match the needs of future users...

TODO: Consider whether debug should be a parameter.


JDKcompile

public static boolean JDKcompile(String fileName,
                                 String classPath)
Try to compile a .java file on disk. This will first attempt to use the sun.java.tools.javac() method, then (if that is unavailable) fall back upon shelling out to a command line and running javac there.

NOTE: This must be _compiled_ with sun.java.tools.* (tools.jar) available. We could change that to use reflection instead, if we accept some overhead... minor compared to the cost of running the compiler!

This has complications on some platforms. For example, under Microsoft Visual Java ++ (at least, as installed on my test system), I found that I had to specify paths to both javac and xerces.jar rather than counting on the shell's path and classpath having been set to reach these. For that reason I've parameterized this method with a few system properties, so you can adapt it to your own system's needs without modifying the code:

org.apache.xml.utils.synthetic.javac
Command line issued to invoke the compiler. Defaults to "javac", which should work in most systems. In VJ++, try setting it to "cmd /c %JAVA_HOME%\\bin\javac.exe"
org.apache.xml.utils.synthetic.moreclasspath
Additional classpath, to be prepended to the one retrieved from java.class.path. Defaults to "" (empty). In VJ++, try setting it to point to your copy of xerces.jar, which may not be found otherwise. TODO: Reconsider prepend versus append!

Returns:
boolean True iff compilation succeeded.

waitHardFor

static int waitHardFor(Process p)
Subroutine: Like p.waitFor, but discards the InterruptedException and goes right back into a wait. I don't want to report compiler success or failure until it really has succeeded or failed... I think.

Returns:
the exitValue() of the process.