[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