【发布时间】:2015-12-14 03:21:21
【问题描述】:
我在互联网上搜索了两个多小时,但没有得出任何结论。
最近我决定将 BouncyCastle 用于 SSL,但我希望它默认关闭,因此 BouncyCastle jar 可能不在类路径中。
private void enableBouncyCastleForSSL() {
if (config.isBouncyCastleEnabled()) {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
}
即使禁用了配置,它也在寻找 BouncyCastle,但由于类加载器错误而失败。 java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
我尝试只移动一行 Security.insertProviderAt(new BouncyCastleProvider(), 1);换成一种新方法,它表现出同样的问题。
但是当我引入一个类并在其中移动 BouncyCastle 时,当配置被禁用时,不会出现类加载器问题
private void setupSSLProvider() {
if (voldemortConfig.isBouncyCastleEnabled()) {
SetupSSLProvider.useBouncyCastle();
}
}
public class SetupSSLProvider {
public static void useBouncyCastle() {
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
}
有些文章声称 Class 仅在第一次使用时才加载。 http://www.programcreek.com/2013/01/when-and-how-a-java-class-is-loaded-and-initialized/
显然在我的例子中,Java8 加载了一个类中引用的类。
所以我的理解是 Java 会在执行类中的第一行代码之前将类加载到一个深度。是这样吗?
【问题讨论】:
-
您是否考虑过查阅 Java 语言规范和 Java 虚拟机规范?而不仅仅是任意的互联网垃圾?您的引文似乎有 14 年的历史,并且依赖于实证调查,而不是官方规范。事实上,引用的 IBM 文档明确指出“基本原则是仅在需要时加载类(或至少看起来以这种方式加载——JVM 在实际加载中具有一定的灵活性,但必须保持类的固定顺序)初始化)”,这应该是对作者的警告。
-
当然这是一个选项,但我认为这是大多数人应该知道的一些标准。有大量关于类加载的文章(3 种类型的类加载器,但没有任何细节)。阅读规范似乎需要一两天的时间,而且语言不是为外行编写的。如果我以不同的方式构建我的问题,何时加载一个类,可以有 3 个答案,引用它的类/方法被加载或何时被访问。如果我必须阅读规范才能得到这个答案,我会感到惊讶。
标签: java java-8 classloader openjdk