Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

the problem for accessing the classes in rt.jar

184 views
Skip to first unread message

zyng

unread,
Apr 16, 2012, 11:47:33 AM4/16/12
to
Hi,
I have asked the similar question before. Thank you for all your help. The issue is still not solved and is very mysterious. By many testing, I have obtained new observations. I think I can ask this question in a better way. Thank you for your help.

As everybody knows, rt.jar is located in jre/lib/ directory. It is *automatically* loaded into Java runtime platform. My code uses some classes in rt.jar. (Whether this is wise or not, this is different issue. Here, I just hope to solve the classpath issue related to rt.jar.)

To check rt.jar is *automatically* loaded by Java, in ant script compile target, I added the option "-verbose". This shows all path of the classes referenced:
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${build.dir}" compiler="modern" fork="yes" debug="on">
<classpath refid="project.classpath"/>
<compilerarg value="-Xlint"/>
<compilerarg value="-verbose"/>
</javac>
</target>

The printout shows that indeed all those JAR files inside jre/lib are loaded:
[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 ..

However, I need this to compile successfully:
<path id="project.classpath">
<fileset dir="/A/B/java/">
<include name="jre/lib/rt.jar"/>
</fileset>
...
</path>

The print out shows
[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/java/jre/lib/rt.jar, ..
(/A/B/java is a solft link to /A/B/jdk1.6.0_25)

To make my story short, my findings is that in order to compile, rt.jar must shows up twice and the path must be different from the first time by these observations:
1) this won't compile:
<path id="project.classpath">
<fileset dir="/A/B/jdk1.6.0_25/">
<include name="jre/lib/rt.jar"/>
</fileset>
...
</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 .., ...,/A/B/jdk1.6.0_25/jre/lib/rt.jar, ..
(the second time rt.jar path is exactly same as the first time, it seems java didn't bother to re-load rt.jar -- my understanding)
2)this will work(copy rt.jar to rt2.jar before hand):
<path id="project.classpath">
<fileset dir="/A/B/jdk1.6.0_25/">
<include name="jre/lib/rt2.jar"/>
</fileset>
...
</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 .., ...,/A/B/jdk1.6.0_25/jre/lib/rt2.jar, ..
(java loads rt2.jar, now my code compiles successfully)
3)this will work(copy jre/lib to somewhere else beforehand)
<path id="project.classpath">
<fileset dir="/X/Y/">
<include name="jre/lib/rt.jar"/>
</fileset>
...
</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 .., ...,/X/Y/jre/lib/rt.jar, ..
(again, the path of the second time referencing rt.jar is different, java then load rt.jar into the platform and my code compiles successfully)

My feeling is that the first time rt.jar loaded, the classes inside rt.jar cannot be accessed by my code. The second time referencing rt.jar, if everything is exactly same as the first reference(including path and the file name), java skips the loading; if there is some difference(different path or different file name) comparing to the first reference, java loads this JAR into the platform, then my code can compile.

Can you help me understand this? I really hope that in the ant script, rt.jar no need to be referenced.

Thank you very much.

markspace

unread,
Apr 16, 2012, 1:22:09 PM4/16/12
to
On 4/16/2012 8:47 AM, zyng wrote:
> <compilerarg value="-verbose"/>

This is smart and a good idea. It shows that the classes are being
loaded, yes?


> The printout shows that indeed all those JAR files inside jre/lib are loaded:

Good!


> However, I need this to compile successfully:
> <include name="jre/lib/rt.jar"/>

This is crazy and there's no need to do this.

>
> (/A/B/java is a solft link to /A/B/jdk1.6.0_25)

This could be an issue. Please remove all links, hard and soft, and use
only one single canonical path. If /A/B on your system is /usr/lib,
use only that. If /A/B is C:\Program Files\Java, use only that.

The Java runtime loads files according to their path names, and may
become confused if it sees the same file twice with a different path
name. I haven't had problems with it myself, but if we're hunting
obscure bugs let's eliminate all possible sources of error.


> To make my story short, my findings is that in order to compile, rt.jar must shows up twice and the path must be different from the first time by these observations:
> 1) this won't compile:
> <path id="project.classpath">
> <fileset dir="/A/B/jdk1.6.0_25/">
> <include name="jre/lib/rt.jar"/>
> </fileset>
> ...
> </path>

This make no sense. Why won't it compile? What error message do you
get? It's just a path, it shouldn't "compile" on its own unless you
have a javac tag or similar.


> <include name="jre/lib/rt2.jar"/>

This is a horrendously bad idea and can only make matters worse. I
think at this point you've messed things up so bad we can't really help
you. Remove ALL extra files from the Java installation directory that
you created, or delete the whole thing and reinstall it to be safe.


> (java loads rt2.jar, now my code compiles successfully)
...
> 3)this will work(copy jre/lib to somewhere else beforehand)

Something is really badly messed up here.


> Can you help me understand this?


Can you delete your entire Java installation and re-install it?
Then please make a very simple "Hello World" program, plus its ant build
file, and post EVERYTHING you are doing here, as well as all error
messages and program output. Here's a simple example for ant:

<http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html>

Lew

unread,
Apr 16, 2012, 5:31:42 PM4/16/12
to
On Monday, April 16, 2012 10:22:09 AM UTC-7, markspace wrote:
> On 4/16/2012 8:47 AM, zyng wrote:
> > <compilerarg value="-verbose"/>
>
> This is smart and a good idea. It shows that the classes are being
> loaded, yes?
>
>
> > The printout shows that indeed all those JAR files inside jre/lib are loaded:
>
> Good!
>
>
> > However, I need this to compile successfully:
> > <include name="jre/lib/rt.jar"/>
>
> This is crazy and there's no need to do this.

Furthermore, rt.jar belongs in the *bootclasspath*, not the classpath, as was stated before. You never need to refer to it explicitly. Your problem lies elsewhere, OP.

> > (/A/B/java is a solft link to /A/B/jdk1.6.0_25)
>
> This could be an issue. Please remove all links, hard and soft, and use
> only one single canonical path. If /A/B on your system is /usr/lib,
> use only that. If /A/B is C:\Program Files\Java, use only that.
>
> The Java runtime loads files according to their path names, and may
> become confused if it sees the same file twice with a different path
> name. I haven't had problems with it myself, but if we're hunting
> obscure bugs let's eliminate all possible sources of error.
>
>
> > To make my story short, my findings is that in order to compile, rt.jar must shows up twice and the path must be different from the first time by these observations:
> > 1) this won't compile:
> >
>
> > <fileset dir="/A/B/jdk1.6.0_25/">
> > <include name="jre/lib/rt.jar"/>
> > </fileset>
> > ...
> > </path>
>
> This make no sense. Why won't it compile? What error message do you
> get? It's just a path, it shouldn't "compile" on its own unless you
> have a javac tag or similar.
>
>
> > <include name="jre/lib/rt2.jar"/>
>
> This is a horrendously bad idea and can only make matters worse. I
> think at this point you've messed things up so bad we can't really help
> you. Remove ALL extra files from the Java installation directory that
> you created, or delete the whole thing and reinstall it to be safe.
>
>
> > (java loads rt2.jar, now my code compiles successfully)
> ...
> > 3)this will work(copy jre/lib to somewhere else beforehand)
>
> Something is really badly messed up here.
>
>
> > Can you help me understand this?
>
>
> Can you delete your entire Java installation and re-install it?
> Then please make a very simple "Hello World" program, plus its ant build
> file, and post EVERYTHING you are doing here, as well as all error
> messages and program output. Here's a simple example for ant:
>
> <http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html>

Follow markspace's advice. You're doing completely the wrong thing trying to use rt.jar explicitly. Don't do that.

--
Lew

Arne Vajhøj

unread,
Apr 17, 2012, 7:51:43 PM4/17/12
to
As states in the previous thread: you should not never ever explicit
specify rt.jar in classpath.

Start by removing all that and then we take it from there.

Arne

zyng

unread,
Apr 18, 2012, 9:13:36 AM4/18/12
to
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.

Andreas Leitgeb

unread,
Apr 18, 2012, 9:48:44 AM4/18/12
to
zyng <xs...@yahoo.com> wrote:
> OK. And also re-phrase my question:
> A)in build.xml file, when not including rt.jar by commenting out rt.jar:

Your experiments and conclusions make sense, but classes in "com.sun.*"
packages are not intended to be used in apps in the first place (and even
less so, if they have ".internal." in their path), so maybe there's even
some explicit trick in Java, that prevents these classes from being visible
to foreign code, when rt.jar is loaded as initial library. By symlinking
(on Linux) you may have outsmarted that mechanism, but you're walking on
very thin ice.

You will most likely run into difficulties later, maybe during any
oncoming patchlevel-update of your jdk, where package
com.sun.xml.internal.fastinfoset.stax
might just disappear with all the classes previously inside it -
without even a mention in release-notes or migration-guides.

> [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] ^

So, to fix your problem, go find a class in a package under "java"
or "javax" that provides a *public* interface to the functionality
of StAXDocumentParser that you really need.

(If I knew the correct class, I'd have mentioned it, but I rarely
do xml-stuff, so others more into it hopefully will step in here.)

markspace

unread,
Apr 18, 2012, 10:45:11 AM4/18/12
to
On 4/18/2012 6:13 AM, zyng wrote:
> OK. And also re-phrase my question: A)in build.xml file, when not
> including rt.jar by commenting out rt.jar:
...
> 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;


Try this, I don't know if it'll work, but it might.

<http://stackoverflow.com/questions/2118198/getting-hold-of-fastinfoset-readers-and-writers>

zyng

unread,
Apr 18, 2012, 11:06:21 AM4/18/12
to a...@logic.at
Thank you. Now I recall why we reach the current stage:

The classes we need for handling fast info documents, e.g. StAXDocumentParser.class, are contained within this JAR file FastInfo_x_x.jar, a free JAR file. So we include the FastInfo JAR file in the classpath. It is referenced in build.xml

However, we also found that all classes inside FastInfo JAR file are also inside rt.jar. Since rt.jar comes with jre automatically, we try to reduce one JAR file in our develop environment by eliminating FastInfo JAR and use rt.jar. Then we reached the current stage.

Anyway, with all the help, I believe that to really solve the problem, we need to re-write the code which handles fast info files. Playing with build.xml cannot solve the problem.

BTW, I think the way of organizing class files(FastInfo JAR -- not sure from Sun or Apache and all its content are also inside rt.jar) is not good.

Thank you all for the help.

zyng

unread,
Apr 18, 2012, 11:35:05 AM4/18/12
to a...@logic.at
My goodness. The problem is solved. By searching Google, I found this link which provides the explanation and the answer:

http://stackoverflow.com/questions/4065401/using-internal-sun-classes-with-javac

I copied his answer here:
"When javac is compiling code it doesn't link against rt.jar by default. Instead it uses special symbol file lib/ct.sym with class stubs.

Surprisingly this file contains many but not all of internal sun classes. In my case one of those more-internal-than-usual classes was sun.awt.event.IgnorePaintEvent.

And the answer to my question is: javac -XDignore.symbol.file

That's what javac uses for compiling rt.jar."

So, in my build.xml, the target "compile", I have:
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${build.dir}" compiler="modern" fork="yes" debug="on">
<classpath refid="project.classpath"/>
<compilerarg value="-Xlint"/>
<compilerarg value="-verbose"/>
<compilerarg value="-XDignore.symbol.file"/>
</javac>
</target>

In project.classpath, I don't need to explicitly reference rt.jar at all! Now it compiles fine.

Andreas Leitgeb

unread,
Apr 18, 2012, 11:50:23 AM4/18/12
to
zyng <xs...@yahoo.com> wrote:
> Anyway, with all the help, I believe that to really solve the
> problem, we need to re-write the code which handles fast info
> files. Playing with build.xml cannot solve the problem.

Why do you not just re-add the separate FastInfoset*.jar, now
that you've learnt not to use rt.jar's guts? ;-)
I think, that would even be the *correct* solution.

> BTW, I think the way of organizing class files(FastInfo JAR --
> not sure from Sun or Apache and all its content are also inside
> rt.jar) is not good.

Probably some of the rt.jar classes themselves depend on that libary,
but this dependency is not something that applications should depend
on being there. If an app needs FastInfoset, then it should include
it on its own...

Yes, it's duplication, but that means also de-coupling: you could
just as well use a newer or older version of it than the one hidden
in rt.jar

Andreas Leitgeb

unread,
Apr 18, 2012, 12:02:02 PM4/18/12
to
zyng <xs...@yahoo.com> wrote:
> http://stackoverflow.com/questions/4065401/using-internal-sun-classes-with-javac
> I copied his answer here:
> "When javac is compiling code it doesn't link against rt.jar by default.
> Instead it uses special symbol file lib/ct.sym with class stubs.

I'm glad to have learnt what "trick" it is, whose existence I
merely deduced from the symptoms you described.

Still, it's a bad thing to depend on internal classes, even if you
managed to get it to work (for now).

markspace

unread,
Apr 18, 2012, 12:02:16 PM4/18/12
to
On 4/18/2012 8:35 AM, zyng wrote:

> I copied his answer here: "When javac is compiling code it doesn't
> link against rt.jar by default. Instead it uses special symbol file
> lib/ct.sym with class stubs.

> And the answer to my question is: javac -XDignore.symbol.file


Sweet. Thanks for posting that. I think you've helped us more than we
helped you. Much appreciated!


zyng

unread,
Apr 18, 2012, 1:49:17 PM4/18/12
to
On Wednesday, April 18, 2012 12:02:16 PM UTC-4, markspace wrote:
>
> Sweet. Thanks for posting that. I think you've helped us more than we
> helped you. Much appreciated!

I have to thank Andreas Leitgeb for his first reply, not with the answer, but with some good content pointing me to the right direction.
Sparked by his reply, with myself several diggings, finally I found the answer.

This is the reason I come to this news group.

Andreas Leitgeb

unread,
Apr 18, 2012, 2:49:49 PM4/18/12
to
zyng <xs...@yahoo.com> wrote:
> On Wednesday, April 18, 2012 12:02:16 PM UTC-4, markspace wrote:
>> Sweet. Thanks for posting that. I think you've helped us more than we
>> helped you. Much appreciated!
> I have to thank Andreas Leitgeb for his first reply,

You're welcome :-)

Arne Vajhøj

unread,
Apr 18, 2012, 9:07:54 PM4/18/12
to
You should avoid using anything undocumented from rt.jar.

It should not be a big problem using the FastInfo_x_x.jar - you
are not charged per jar file.

You should be able to get newest version from here:
http://search.maven.org/#browse|-268259873

Arne


0 new messages