Java:使用bootclasspath防止找到H2驱动程序
如果我从Oracle JDK 7源代码构建自己的修补版Java:使用bootclasspath防止找到H2驱动程序,java,jdbc,h2,classnotfoundexception,bootclasspath,Java,Jdbc,H2,Classnotfoundexception,Bootclasspath,如果我从Oracle JDK 7源代码构建自己的修补版rt.jar(称为my-rt.jar),并将其与bootclasspath机制挂钩,如下所示 $ java -Xbootclasspath/p:/path/to/my-rt.jar -cp /path/to/h2-1.3.174.jar main 然后,我甚至无法在应用程序开始时加载H2驱动程序: // Application's main.java public class main { public static void ma
rt.jar
(称为my-rt.jar
),并将其与bootclasspath
机制挂钩,如下所示
$ java -Xbootclasspath/p:/path/to/my-rt.jar -cp /path/to/h2-1.3.174.jar main
然后,我甚至无法在应用程序开始时加载H2驱动程序:
// Application's main.java
public class main {
public static void main(String[] args) {
// ...
Class.forName("org.h2.Driver"); // Line 145
}
}
上述情况导致以下例外情况:
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)
但是,如果我删除-Xbootclasspath/p开关,并且其他一切都与以前一样,我可以很好地加载驱动程序,应用程序的其余部分也可以很好地工作
那么,在JDBC驱动程序(比如H2)的初始化过程中,是否有什么特殊的事情阻止我使用bootclasspath机制?或者,bootclasspath
机制有什么特别之处,它不允许加载像H2这样的JDBC驱动程序
我没有东西可试了。比如说,
我甚至从源代码中重新构建了H2驱动程序,并确保我的应用程序和驱动程序都使用了相同版本的javac
我已经在Eclipse和命令行中尝试了上述方法
我在两台不同的机器上试过
所有这些都产生相同的异常
顺便说一句,我修补过的my-rt.jar
有一个非常简单的编辑:它只是在java.lang.Object
中添加了一个公共静态int计数器。在上面的Class.forName(…)
行之前,我能够验证在启用bootclasspath
开关时,我确实可以打印计数器的值
奇怪的是,即使我在java.lang.Object
中注释掉这个计数器
字段,但继续预编my-rt.jar
(这与原始的rt.jar
一样好,只是重新编译并预编了n个),即使这样,我也无法找到/加载H2驱动程序
(我也有,但没有得到回应。也许,那些人不认为这是H2问题,所以我在这里问。)我已经搞定了。这就是我所做的
我首先将原始的rt.jar
添加到原始的rt.jar
,如下所示:
$ java -Xbootclasspath/p:/path/to/orig/rt.jar -cp /path/to/h2-1.3.174.jar main
例外消失了!这清楚地告诉我,bootclasspath/p
机制无法干扰H2驱动程序的加载
因此,我随后取消了原始rt.jar
的归档,并将其与my-rt.jar
的未归档内容进行了比较,我发现my-rt.jar
中缺少了多达8000个文件:
$ wc -l *.list
11285 my-rt.jar.list
19059 rt.jar.list
30344 total
因此,很明显,我从官方的src.zip
构建的my-rt.jar
缺少很多东西。难怪H2司机在装货时遇到了麻烦
为了进一步确认,这次我只将修补过的java/lang/Object.class
复制到原始rt.jar
的未归档内容上,瞧,H2驱动程序继续正常加载
因此,名称src.zip
是一个严重的误称。因为它没有构建rt.jar所需的所有内容
,所以应该将其称为partial src.zip
(或者类似的名称)。AFAIK src.zip不包含(部分或全部)sun中的专有类。*
,com.sun.*
和com.oracle.*
软件包。我通过艰苦的学习了解到了这一点。因为这个名字,我很容易错过。正如我所说,这个zip更清晰的名称可能是:partial src.zip
,非专有src.zip
,publicOnly src.zip
,等等。