2011-03-21 83 views
11

到目前为止,我看到的自定义类加载器的示例涉及到URLClassLoader的子类化,并使用该特定实例来加载资源中的类。替换系统类加载器用于包含Jars的Jars类

我一直试图寻找替代方法来替换SystemClassLoader,以便我的ClassLoader可以参考不在类路径中的类。我试过Thread.currentThread().setContextClassLoader,但它似乎没有工作。

这有可能吗?

+0

当你说“这样我的ClassLoader可以查询不在类路径中的类”时,你的意思是像'java.lang。*'等这样的普通系统类还是你的意思是加载额外的第三方类? – Pacerier 2014-08-29 00:24:51

+0

第三方类... – Olaseni 2014-08-29 23:52:54

回答

8

运行JVM与java.system.class.loader属性:

java -Djava.system.class.loader=myClassLoader myApplication 
+3

我正在寻找一种解决方案,该解决方案排除修改JVM命令行 – Olaseni 2011-03-24 05:55:23

+0

如果您想要替换系统类加载器,则不存在此类解决方案。您可以在代码中创建专有的类加载器并使用它加载类,但它不会是系统类加载器。通常创建专有的类加载器对于大多数情况是一种充分的解决方案 – Tarlog 2011-03-24 08:03:04

11

尽管这是一个老问题,也的确是更换系统的ClassLoader的方式。 但是,您可能会得到比您讨价还价更多的反思。

 Field scl = ClassLoader.class.getDeclaredField("scl"); // Get system class loader 
     scl.setAccessible(true); // Set accessible 
     scl.set(null, new YourClassLoader()); // Update it to your class loader 

这应该在Oracle JVM上工作。

+2

这当然是一个黑客攻击,取决于一个私有变量,它可能会在Java版本之间发生变化,但它允许我解决第三方依赖项中的单个jar和代码问题,该第三方依赖项调用System.getClassLoader()来加载类。把一个jar的类加载器推到最后。 – Gus 2014-09-11 07:28:18

+0

@Xyene在完成我的工作之后 - 如果将类加载器返回到URLClassLoader.getSystemClassLoader(),应用程序的行为是否正常? – ha9u63ar 2017-10-04 16:40:20

+0

@ ha9u63ar我想这取决于你的用例;如果你不小心,很可能你的类会出现可见性问题(例如,从系统类加载器加载的类A将无法从你的类中看到类B)。我做了这样的事情已经有几​​年了,但是把系统加载器放回去可能没有什么好处。 – Xyene 2017-10-04 17:19:29