2012-08-16 53 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