May I add a footnote to the FAQ and forum discussions about the XMLBeans scomp script not finding javac? I had a considerable problem with this, and it seems to be caused by two issues interacting, one in XMLBeans, the other in the Java interpreter. The following findings refer to Java 6 (version 1.6.0_03) and XMLBeans version 2.3.0 installed on Windows XP SP2.

The algorithm by which XMLBeans finds tools like javac is roughly this:

- first find where the java.home system property points, which should be 'the Java installation directory', e.g. the JDK's copy of the run time, ...\jdk1.6.0_03\jre for the current release of Java 6 SDK;

- then look for a file called javac or javac.exe in several places relative to here such as ..\bin;

- if the file is found, use the full path to it to construct the compilation command, otherwise just use javac and 'hope that the tool is on the Path'.

The Java-related issue is that if you do a default installation of the Java 6 SDK, it also installs a normal runtime environment ( in ...\jre1.6.0_-3), and just running "java" or "java.exe" will always return this directory as java.home, regardless of what you do with setting environment variables or putting directories in the path. The reason is that although all copies of java.exe supplied with the SDK or JRE are identical, the value they give for java.home depends on what directory they are run from; that is the directory containing the executable, regardless of how it was found by the OS. If it is run from ...\jdk1.6.0_03\bin or ...\jdk1.6.0_03\jre\bin it reports ...\jdk1.6.0_03\jre, otherwise ...\jre1.6.0_03. The twist in the plot is that the default installation also puts another identical copy of java.exe into the Windows System directory (...\Windows\System32) to ensure that the newly installed version of Java is run by default, no matter from where. Since Windows looks in System32 before consulting the path, java.exe is never executed from ...\jdk1.6.0_03\bin and so java.home is always ...\jdk1.6.0_03\jre, and XMLBeans doesn't find javac.exe. The workaround is now obvious - rename or replace the copy of java.exe in ...Windows\System32, and ensure that ...\jdk1.6.0_03\bin is on the path, if necessary ahead of any other directories which contain further versions from any source. (This is why the FAQ suggestion of modifying scomp to run java explicitly from ...\jdk1.6.0_03\bin also works.) This behaviour on the part of Java seems a little bizarre, and at the very least it should be documented in the SDK installation instructions; I shall take this up with java.net

But, you say, if XMLBeans doesn't find javac.exe where it expects to, it just runs javac, and ...\jdk1.6.0_03\bin is on the path, so it should still work. That is the intention, but this route doesn't do the job either. The method which looks for Java tools (CodeGenUtil.findJavaTool) returns a File object set up from the file spec which worked, or just the requested tool name (javac) if no file was found. Unfortunately, the invoker of this method (CodeGenUtil.externalCompile) uses getAbsolutePath() on the returned File, and this applies the current default device and directory if no path was supplied. So externalCompile ends up trying to run javac explicitly from the default directory, and it still fails.

At the simplest level the fix for this within XML Beans seems obvious - use getPath() instead of getAbsolutePath(). This returns the string that was used to create the File object, so if one of findJavaTool's attempts to locate javac.exe succeeds, the correct path will be used. In addition, if the File based just on javac is returned, no path will be supplied, and javac will be found via the path environment variable.

However, it is arguable that the confusion has arisen because a File object is not actually the right thing for findJavaTool to return in the first place. What the caller really wants is just a string which can be used to construct a shell command, so returning a string would be both more explicit and safer. As findJavaTool is private to CodeGenUtil, the ramifications of doing this are quite small.

I must add that I don't know whether these suggestions might have undesirable implications for other platforms, or indeed for other versions of Windows.



In the long term, it should eventually be possible to use the new (supported) compiler API as described in .../docs/api/javax/tools/package-summary.html and ...docs/api/javax/tools/JavaCompiler.html, when that is implemented.



John Ash


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to