OK. And also re-phrase my question:
A)in build.xml file, when not including rt.jar by commenting out rt.jar:
<path id="project.classpath">
<!--fileset dir="$/A/B/jdk1.6.0_25">
<include name="jre/lib/rt.jar"/>
</fileset-->
<pathelement location="${build.dir}"/>
<fileset dir="${externals.dir}">
<include name="abc.jar"/>
<include name="xyz.jar"/>
<include name="junit.jar"/>
</fileset>
</path>
I got these error message
compile:
[javac] C:\my_work\build.xml:47: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to fals
for repeatable builds
[javac] Compiling 407 source files to C:\my_work\build
[javac] C:\my_work\src\abc\efg\xml\MyXmlUtils.java:27: package com.sun.xml.internal.fastinfoset.stax does not exist
[javac] import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
[javac] ^
[javac] C:\my_work\src\abc\efg\xml\MyXmlUtils.java:28: package com.sun.xml.internal.fastinfoset.stax does not exist
[javac] import com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer;
[javac] ^
[javac] C:\my_work\src\abc\efg\xml\MyXmlUtils.java:29: package com.sun.xml.internal.txw2.output does not exist
...
Those packages are located inside rt.jar. And everybody agrees, rt.jar is automatically loaded into the platform. Since I added the option "-verbose" in javac, I saw this print out, which clearly shows rt.jar is in the class path:
[javac] [search path for class files: /A/B/jdk1.6.0_25/jre/lib/resources.jar,/A/B/jdk1.6.0_25/jre/lib/rt.jar,/A/B/jdk1.6.0_25/jre/lib/sunrsasign.jar ..
Clearly, my code cannot access /jre/lib/rt.jar so compiling failed. Why my code cannot access rt.jar?
B)If including rt.jar in the project.classpath:
<path id="project.classpath">
<fileset dir="$/A/B/jdk1.6.0_25">
<include name="jre/lib/rt.jar"/>
</fileset>
<pathelement location="${build.dir}"/>
<fileset dir="${externals.dir}">
<include name="abc.jar"/>
<include name="xyz.jar"/>
<include name="junit.jar"/>
</fileset>
</path>
I got exactly the same error message. The classpath shown by -verbose is:
[javac] [search path for class files: /A/B/jdk1.6.0_25/jre/lib/resources.jar,/A/B/jdk1.6.0_25/jre/lib/rt.jar,/A/B/jdk1.6.0_25/jre/lib/sunrsasign.jar .. /A/B/jdk1.6.0_25/jre/lib/rt.jar ..
"/A/B/jdk1.6.0_25/jre/lib/rt.jar" shows up twice, which makes sense(one is due to automatically loaded, one is due to explicit reference in my build.xml).
C)if I make a soft link which points to /A/B/jdk1.6.0_25, with a name, say, "/fs/soft_link" and in project.classpath:
<path id="project.classpath">
<fileset dir="$/fs/soft_link">
<include name="jre/lib/rt.jar"/>
</fileset>
<pathelement location="${build.dir}"/>
<fileset dir="${externals.dir}">
<include name="abc.jar"/>
<include name="xyz.jar"/>
<include name="junit.jar"/>
</fileset>
</path>
On linux, this will work, because linux does not "translate" the soft link back to its original path:
[javac] [search path for class files: /A/B/jdk1.6.0_25/jre/lib/resources.jar,/A/B/jdk1.6.0_25/jre/lib/rt.jar,/A/B/jdk1.6.0_25/jre/lib/sunrsasign.jar .. /fs/soft_link/jre/lib/rt.jar ..
"rt.jar" shows up twice, with different path. JAVA clearly re-loaded rt.jar, from /fs/soft_link path and my code now can grap the classes they need.
On PC, it does not work. Somehow, PC "translate" the soft link into its real path, so again, "/A/B/jdk1.6.0_25/jre/lib/rt.jar" shows up twice. My guess is that JAVA does not do repeated loading. As case A) above showed, the first time loading of "/A/B/jdk1.6.0_25/jre/lib/rt.jar" does not help my code.
D)this case works on both Linux and PC. Just for testing purpose only:
within /A/B/jdk1.6.0_25/jre/lib/, copy rt.jar to rt2.jar, in project.classpath:
<path id="project.classpath">
<fileset dir="$/A/B/jdk1.6.0_25">
<include name="jre/lib/rt2.jar"/>
</fileset>
<pathelement location="${build.dir}"/>
<fileset dir="${externals.dir}">
<include name="abc.jar"/>
<include name="xyz.jar"/>
<include name="junit.jar"/>
</fileset>
</path>
Now compiling is fine.
[javac] [search path for class files: /A/B/jdk1.6.0_25/jre/lib/resources.jar,/A/B/jdk1.6.0_25/jre/lib/rt.jar,/A/B/jdk1.6.0_25/jre/lib/sunrsasign.jar .. /A/B/jdk1.6.0_25/jre/lib/rt2.jar ..
Clearly, JAVA loaded rt2.jar since "/A/B/jdk1.6.0_25/jre/lib/rt2.jar" looks different from "/A/B/jdk1.6.0_25/jre/lib/rt.jar", at least in JAVA's view. Now my code have their classes to grab.
E)Needless to say, if copying rt.jar from /A/B/jdk1.6.0_25/jre/lib/ to somewhere else, say, /C/D/jre/lib, now in project.classpath:
<path id="project.classpath">
<fileset dir="$/C/D">
<include name="jre/lib/rt.jar"/>
</fileset>
<pathelement location="${build.dir}"/>
<fileset dir="${externals.dir}">
<include name="abc.jar"/>
<include name="xyz.jar"/>
<include name="junit.jar"/>
</fileset>
</path>
Compiling is fine.
[javac] [search path for class files: /A/B/jdk1.6.0_25/jre/lib/resources.jar,/A/B/jdk1.6.0_25/jre/lib/rt.jar,/A/B/jdk1.6.0_25/jre/lib/sunrsasign.jar .. /C/D/jre/lib/rt.jar ..
To summarize what I saw,
1)"/A/B/jdk1.6.0_25/jre/lib/rt.jar" will be loaded automatically regardless of including rt.jar in the project.classpath or not. However, this loading do not serve my code.
2)in build.xml, project.classpath, when referencing "rt.jar", it needs either the path be different or the file name be different, somehow fool JAVA to really re-load this JAR file. Only this second loading of rt.jar can help my code. Very strange!
Thank you very much.
Thank you very much.