2012-08-16 55 views
0

我從網絡獲取字節碼。我將字節數組轉換爲類類Java的字節碼

package l2soft.utils; 

public final class CustomClassLoader extends ClassLoader { 

public static CustomClassLoader _instance; 
public static CustomClassLoader getInstance() { 
    return _instance; 
} 

public void defineCustomClass(byte[] bytecode) { 
    Class<?> clazz = defineClass(null, bytecode, 0, bytecode.length); 
    resolveClass(clazz); 
} 

} 

但是當應用程序啓動時,無法找到派生類。

The import test.Test1 cannot be resolved 

(與收到類compilled)

注:我不知道類文件名。我並不需要申請一類,服務器本身發送

UPD:

package l2soft.utils; 

import java.util.HashMap; 
import java.util.Map; 

public final class CustomClassLoader extends ClassLoader { 

    private Map<String, Class<?>> cache; 

    public static CustomClassLoader _instance; 
    public static CustomClassLoader getInstance() { 
     return _instance; 
    } 

    public CustomClassLoader(ClassLoader parent) { 
     super(ClassLoader.getSystemClassLoader()); 
     _instance = this; 
     cache = new HashMap<String, Class<?>>(); 
    } 

    public void defineCustomClass(byte[] bytecode) { 
     Class<?> clazz = defineClass(null, bytecode, 0, bytecode.length); 
     resolveClass(clazz); 
     cache.put(clazz.getName(), clazz); 
    } 

    @Override 
    public synchronized Class<?> findClass(String name) throws ClassNotFoundException { 
     Class<?> result = cache.get(name); 

     if(result == null) 
      super.findClass(name); 

     return result; 
    } 

} 

這是我的自定義類加載器。 SomeClass通過這個類加載器和tes.Test1加載。但我看到錯誤:import test.Test1無法解析。這CustomClassLoader設置爲默認加載器(-Djava system.loader = l2soft.utils.CustomClassLoader)

+0

你是下載所有必需的課程還是隻下載一個課程? – MadProgrammer 2012-08-16 23:34:51

+0

'-verbose:class'是你的朋友遇到麻煩。 – biziclop 2012-08-17 10:27:42

回答

1

既然你不要在你的問題中指定,我會假設你在一個名爲SomeClass類進口test.Test1。我還假定當你運行JVM時,這個類在你的初始類路徑中(這似乎暗示了問題的本質)。

當您的應用程序啓動時,它將使用默認的類加載器加載類路徑中的所有類(包括SomeClass)。爲確保SomeClass能夠正常運行,它還必須確保所導入的所有其他類(包括test.Test1)也被加載。

問題是,由於test.Test1不是在類路徑上,默認的類加載器無法解決它,因此錯誤。 test.Test1直到用您的自定義加載程序手動加載它之後才能解析,之後的是從類路徑(當應用程序實際由JVM運行時)的初始類加載之後發生的。

這可能不是一件容易解決的問題。可能最簡單的方法是使test.Test1在類路徑上實現某個接口(如Test),其中。然後,在SomeClass中,您可以導入Test並使用Test引用而不是test.Test1引用來引用您的動態加載的類的對象。

+0

SomeClass加載後test.Test1類。我嘗試使用我的CustomClassLoader作爲系統(-Djava.system.loader)並用緩存覆蓋findClass,但結果沒有改變。 – IOException 2012-08-16 23:46:03

+0

如您所說,如果在載入'test.Test1'後加載'SomeClass',那麼可能'test.Test1'實際上未被正確加載,或者加載'SomeClass'的加載器與另一個加載器不同加載'test.Test1'並且不是它的後代(因此,'test.Test1'被加載,但不是在類別層次結構中'SomeClass'可以訪問)。另外,我相信這是'-Djava.system.class.loader',而不是'-Djava.system.loader'。 – Mac 2012-08-17 00:06:10

+0

更新第一篇文章。 – IOException 2012-08-17 10:23:42