眼前的情况并不像标题所暗示的那么简单。
通过 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