2016-09-19 69 views
0

我正在嘗試使用自定義類加載器來加載隨機.class文件,該文件可能位於文件系統的任何位置。我寫了我的類加載器來擴展ClassLoader,覆蓋了findClass()loadClass()方法,並讀入類文件的字節流。產生的問題是在試圖調用ClassLoader.defineClass()對於錯誤的目錄結構,解決方法NoClassDefFoundError

確切的錯誤我得到的是當:

Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: com/foo/bar/Test) 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 

我知道問題是本地類加載功能不喜歡的事實,Test.class不生活在/someDir/com/foo/bar/。有什麼辦法可以使這項工作?我的類加載器已經有代碼來檢查定義的類是否符合特定的包。我真的不明白爲什麼本地方法會拒絕這個(除了安全性,我不需要在這個用例中,然後事件,讓我自己拍攝腳)。

+0

你是否在加載類的控制,因此可以修改它?如果是這樣,是否需要包名?如果沒有,只需不定義一個包名稱,那麼你應該能夠從任何你想要的目錄加載類。包名實際上是類的一部分,因此需要某些字節處理框架,如[Javassist](http://jboss-javassist.github.io/javassist/)加載字節,然後更新「類」表示通過類加載器實際加載。 –

+0

稍後,我將所有加載的類放在特定的包中,因此我依賴於特定的包名。但是,id喜歡將該類文件放置在目錄結構中的任何位置,並仍然加載它。 – bss36504

+0

然後看看Javassit(或其他字節操縱框架) –

回答

1

本機類加載器,即ClassLoader.defineClass1,不知道關於目錄結構的任何內容。它只是加載一個字節數組。

錯誤消息表明,作爲參數傳遞給defineClass的二進制名稱與從類數據字節中發現的實際名稱不匹配。當調用defineClass時,最簡單的解決方法是設置name=null

注意:您不能通過將其移動到不同的目錄來更改類的包。包名稱嵌入在類文件數據中。您必須使用正確的package指令重新編譯源文件,或者在加載時使用字節碼工具框架修改類文件字節。

+0

哇,我簡直不敢相信那是簡單的。這似乎工作,非常感謝你! – bss36504