【问题标题】:Custom Java classloader and inner classes自定义 Java 类加载器和内部类
【发布时间】:2011-03-25 18:12:06
【问题描述】:

我有这个从 zip 加载类的方法(在我自己的类加载器中):

ZipInputStream in = new ZipInputStream(new FileInputStream(zip));
ZipEntry entry;
while ((entry = in.getNextEntry()) != null) {
    if (!entry.isDirectory()) {
        byte[] buffer = new byte[(int) entry.getSize()];
        in.read(buffer);
        if (!entry.getName().endsWith(".class"))
            continue;
        String name = entry.getName().replace(".class", "").replace("/", ".");
        Class<?> cls = this.defineClass(name, buffer, 0, buffer.length);
        this.resolveClass(cls);
    }
}

我尝试加载的 zip 如下所示:

TestClass.class
TestClass$SomeOtherInnerClass.class 

我的问题是defineClass() 无法加载TestClass$SomeOtherInnerClass。如果这个类是在实际的 TestClass 之前加载的,我会得到这个:

java.lang.NoClassDefFoundError: TestClass

我也尝试先加载 TestClass.class,但随后我收到此错误:

java.lang.ClassFormatError: Wrong InnerClasses attribute length in class file TestClass 

是不是我做错了什么?

【问题讨论】:

  • 我也有同样的问题,如何加载内部类?,我的 A 类已正确加载,但我的 A$b1 类没有...没有找到加载内部类的方法。 ..你有什么进展吗?

标签: java class classloader inner-classes


【解决方案1】:

我看起来你可能没有覆盖ClassLoader.findClass()。如果不这样做,您正在扩展的 ClassLoader 不知道如何找到这些类。

用简单地在private static Map&lt;String, Class&lt;?&gt;&gt; 中查找类的东西覆盖该函数。加载每个类时,将其放入该地图中。

困难在于以正确的顺序加载类,因为您当前的实现不允许您跳回搜索 Zip 并从新的 findClass() 方法调用 defineClass()

【讨论】:

  • 我当前的代码如下所示:link 但我的问题仍然存在,如果我尝试先加载 TestClass 它会抛出错误,因为它找不到内部类(因为它尚未定义)我没有不知道怎么解决这个:/
【解决方案2】:

至少存在一个错误,即您没有(必然)完全读取缓冲区(并且ZipEntry.getSize 可能会返回-1)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多