我有一个自定义URLClassLoader,它从正常类路径之外的jar文件中加载几个类。到目前为止,非常好。
我的问题是,当我需要由ClassLoader加载的类时,我不能每次调用此ClassLoader,因为这些类可能由第三方库使用。出于这个原因,我通过反射将类添加到当前的Thread ClassLoader中:
ProtectionDomain pd = getClass().getProtectionDomain();
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final java.lang.reflect.Method clM = ClassLoader.class.getDeclaredMethod("defineClass", Class.class);
clM.invoke(classLoader, className, byteContent, 0, byteContent.length, pd);
但是当在Thread ClassLoader中调用findClass并且我还没有添加请求的类时,我得到NoClassDefFoundException。当然。
我现在的问题是,有没有办法将我的ClassLoader放在我的应用程序的全局类加载链中?由于我的ClassLoader可以包含在Web应用程序中并作为war文件部署,因此无法使用系统ClassLoader的Java选项。我也尝试使用Thread.currentThread().setContextClassLoader()
但是一旦创建了新的Thread,它当然没有设置我的ClassLoader。
我在网上搜索了好几天但找不到任何解决方案。
感谢您的帮助和任何建议。
祝你好运, 格里
答案 0 :(得分:0)
不是真的,特别是如果您希望它与作为Web应用程序运行兼容。
你需要解决多个问题。允许Web容器在安全管理器下运行,这将使您的代码无法工作(即,他们可以禁止访问文件系统和/或禁止创建ClassLoader)。 Java旨在允许安全加载移动代码(它最初是针对所有东西,有线机顶盒),因此您可以想象应用程序即时修改系统类加载器的能力不是建筑学。
对于应用程序,您应该做的是(1)将您在其中专门加载这些类的JAR文件放入系统类路径中,或者(2)加载应用程序在自定义类加载器中,然后让自定义类加载器加载您的类(基本上与您现在的方式相同)。在同一个类加载器中加载第三方库。现在你会好起来的,无论你的意思是什么“可能被第三方图书馆使用”(这让我感到困惑,我不确定他们可能会使用什么技术,这很重要。)
对于webapp,您应该在Web应用程序中捆绑所需的类。您试图从其他地方加载类,从而打败了Web应用程序设计; Web应用程序和.war的想法是让这些东西自成一体。
所以你这样做是错误的。如果您坚持以错误的方式进行操作,可能会出现各种非便携式黑客攻击,以便在特定情况下使代码正常工作,但我现在只打算写一个答案,看看你是什么认为。 :)