[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmlbeans-dev
Subject:    Causes of scomp/javac problem in Windows
From:       "John Ash" <jfa.subs1 () ntlworld ! com>
Date:       2008-02-11 16:26:01
Message-ID: 006601c86cca$cc299550$4c00a8c0 () lion
[Download RAW message or body]

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: dev-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: dev-help@xmlbeans.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic