Вопрос

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,

  1. 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.

  2. I've tried the above both from Eclipse and from command-line.

  3. 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.)

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top