2011-11-01 21 views
0

我正在寫一個自定義類加載器來加載我的一些類(不是全部)。Java,自定義類加載器的問題

類加載器是非常簡單的:

public Class loadClass(String className, boolean resolve) throws ClassNotFoundException { 
    Class cls=findLoadedClass(className); 
    if(cls!=null) { 
     return cls; 
    } 
    // Search first for encrypted classes 
    cls=decryptClass(className); 
    if(cls==null) { 
     // Then try with default system classloader 
     cls=super.loadClass(className, resolve); 
    } 
    return cls; 
} 

這也是我如何使用它:

// In my Launcher class 
public static void main(String[] args) { 
    MyClassLoader loader=new MyClassLoader(); 
    try { 
     final Class main=loader.loadClass("com.MyAppMain"); 
     Method toInvoke=main.getMethod("main", args.getClass()); 
     toInvoke.invoke(main, new Object[]{args}); 
    } 
    catch(Exception ex) { 
    } 
} 

都似乎要被罰款在我小的測試項目,但是當我使用這部分代碼在我的大項目(使用spring + hibernate和IoC的客戶端 - 服務器應用程序)不起作用。 我沒有在我的類加載器particulate異常,但例如,新的Socket實例拋出一個「java.net.ConnectException:連接拒絕」沒有一個真正的原因...

其他問題是我的主要形式不成爲可見......以及其他奇怪的問題。

所以,這個問題,是由我的類加載器引起的這些問題,以不同的方式加載不同類的類?


編輯1

我的項目中使用的彈簧,所以我用@Autowired或有時

springApplicationContext.getBean(clazz); 

注入一個bean。

問題是春天找不到我的豆,如果這些類被加密(所以他們需要由我的類加載器加載)。 這個錯誤有一個解決方法嗎? 謝謝。


編輯2

我已在春天的ClassPathXmlApplicationContext我的類加載器,現在我注意到,春季使用我的類加載器加載豆類,但儘管這樣,它拋出一個org.springframework.beans.factory.NoSuchBeanDefinitionException因爲它找不到豆類......我能做什麼? 感謝

+0

如果你的類加載......你不必與你的類加載器的問題。沒有連接的套接字與此無關。 –

+1

我認爲您的問題不是由自定義類加載直接導致的。嘗試將問題分解爲較小的問題並進行調試。將斷點放入'java.net.Socket'並查看它嘗試連接的位置。我相信你沒有正確地得到參數。 – AlexR

+0

謝謝大家,我認爲問題在於Spring和IoC與我的類加載器。我編輯第一個問題的更多細節。 – blow

回答

0

我看到兩件事情,可能是值得探討:

  • 的代碼使類加載器父最後。總會有這樣的風險導致微妙的課堂加載問題。
  • 也許它只是線程上下文類加載器沒有正確設置。
+0

謝謝,如果問題是這樣的,我該如何解決我的問題? – blow

+0

**如果**你的問題是由其中之一引起的,那麼使你的類加載器爲父類第一和/或設置上下文類加載器。 –

+0

再次感謝,我嘗試爲Thread.currentThread設置我的類加載器,但它不起作用,所以我嘗試爲Spring ClassPathXmlApplicationContext設置類加載器,但它不再工作...所以我無法找到位置是問題。 – blow

0

我不是很擅長類加載器,但是從你的代碼中只能假設,如果你的類加載器找不到類,它將重定向到系統類加載器。當你運行應用程序獨立時,它可能正常工作,就像在你的示例中一樣,但如果它是在應用程序服務器上運行的Web應用程序,它將會失敗。

應用程序服務器通常會創建一個大的類加載器層次結構,並具有用於加載應用程序類的單獨的類加載器。在這種情況下,系統類加載器對Spring相關的類一無所知,因此無法加載它們。

您必須記住,同一個類可能會被幾個類加載器加載,如果您嘗試比較來自不同類加載器的同一類,它將會失敗。

在你的情況下,我會在MyClassLoader構造函數中設置父類加載器。作爲父類加載器,我可以使用MyClassLoader.class.getClassLoader()。

public class MyClassLoader extends ClassLoader 
{ 
    public MyClassLoader() 
    { 
     super(MyClassLoader.class.getClassLoader()); 
    } 

    // other code 
} 

希望這可以幫助:)