Reputation: 3937
If I build my own, tinkered version of rt.jar
(called my-rt.jar
) from the Oracle JDK 7 sources and hook it in with the bootclasspath
mechanism, like this,
$ java -Xbootclasspath/p:/path/to/my-rt.jar -cp /path/to/h2-1.3.174.jar main
then, I can't even load the H2 driver at the beginning of my application:
// Application's main.java
public class main {
public static void main(String[] args) {
// ...
Class.forName("org.h2.Driver"); // Line 145
}
}
The above results in the following exception:
Exception in thread "main" java.lang.ClassNotFoundException: org/h2/Driver
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at main.main(main.java:415)
However, if I remove the -Xbootclasspath/p
switch and with everything else the same as before, I can load the driver fine, and the rest of application too works fine too.
So, is there anything peculiar going on inside the initialization of a JDBC driver (such as H2's) that's preventing me from using the bootclasspath mechanism? Or, is there anything peculiar about the bootclasspath
mechanism that it won't allow the loading of a JDBC driver like H2?
I'm out of things to try. For example,
I've even re-built the H2 driver from its sources and made sure that both my application and the driver are using the identical version of javac
.
I've tried the above both from Eclipse and from command-line.
I've tried it on 2 different machines.
All yield the same exception.
Btw, my tinkered my-rt.jar
has a very simple edit to it: It simply adds a public static int counter
to java.lang.Object
. Before the Class.forName(...)
line above, I'm able to verify that I can indeed print the value of counter
when the bootclasspath
switch is enabled.
The strange thing is, even if I comment out this counter
field in java.lang.Object
but continue prepending my-rt.jar
(that is as good as the original rt.jar
, only recompiled andn prepended), even then I cannot get the H2 driver to be found/loaded!
(I've posted this on the H2 google group too but getting no response there. Maybe, those folks don't think this is an H2 problem, so I'm asking here.)
Upvotes: 3
Views: 476
Reputation: 3937
I've nailed it. Here's what I did.
I first prepended the original rt.jar
to the original rt.jar
, like so:
$ java -Xbootclasspath/p:/path/to/orig/rt.jar -cp /path/to/h2-1.3.174.jar main
And the exception disappeared! This clearly told me that the bootclasspath/p
mechanism was no way interfering with the loading of the H2 driver.
So, I then unjarred the original rt.jar
and diff
'ed it with the unjarred contents of my-rt.jar
, I found around a whopping 8000 files missing from my-rt.jar
:
$ wc -l *.list
11285 my-rt.jar.list
19059 rt.jar.list
30344 total
So, obviously, my-rt.jar
that I built from the official src.zip
had tons of stuff missing from it. No wonder, H2 driver was having loading troubles.
To further confirm, this time I copied over only my tinkered java/lang/Object.class
to the unjarred contents of the original rt.jar
, and lo and behold, the H2 driver continued to load just fine.
Thus, the name src.zip
is a terrible misnomer. Because it does not have everything needed to build rt.jar
, it should be called partial-src.zip
(or, something like that) instead.
Upvotes: 1