眼前的情况并不像标题所暗示的那么简单。
通过 JWS 运行的 Java 1.6_17。
我有一个类,假设MyClass
它的一个实例成员变量是来自错误的 3rd 方库的类型,在该类初始化期间,它动态尝试使用Class.forName(String)
. 在其中一种情况下,它碰巧动态调用: .此类Class.forName("foo/Bar")
名称不遵循二进制名称的 JLS 并最终导致java.lang.NoClassDefFoundError: foo/Bar
.
我们有一个自定义项ClassLoader
,我添加了一个 sanitize 方法ClassLoader.findClass(String)
并ClassLoader.loadClass(String)
解决了这个问题。
我可以这样称呼:
myCustomClassLoader.findClass("foo/Bar")
然后加载类没有任何问题。但是即使我提前加载了类,我仍然会在以后得到异常。这是因为在 which 的初始化过程中MyClass
,Bar
它们的代码最终会Class.forName("foo/Bar")
在某个地方调用静态块。如果它尝试使用的 ClassLoader 是我的自定义类加载器,这实际上是可以的。但事实并非如此。它是com.sun.jnlp.JNLPClassLoader
不做这种卫生的,因此是我的问题。
我已确保将Thread.currentThread().getContextClassLoader()
其设置为我的自定义类加载器。但这(如您所知)没有效果。main()
由于我阅读了一些东西,我什至将它设置为我做的第一件事,而且仍然MyClass.class.getClassLoader()
是 JNLPClassLoader。如果我可以强制它不是 JNLPClassLoader 而是使用我的,问题就解决了。
如何通过在类初始化期间进行的静态 Class.forName("foo/Bar") 调用来控制使用哪个 ClassLoader 来加载类?我相信如果我可以强制MyClass.class.getClassLoader()
返回我的自定义类加载器,我的问题就会得到解决。
如果有人有想法,我愿意接受其他选择。
TL;DR:帮助我强制使用我选择的类加载器Class.forName(String)
引用第三方库中的所有调用。MyClass