2011-03-21 74 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