简体   繁体   English

自定义Java类加载器和内部类

[英]Custom Java classloader and inner classes

I have this method (in my own classloader) that loads classes from zip: 我有这个方法(在我自己的类加载器中)从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);
    }
}

The zip that im trying to load looks like this: 我试图加载的zip看起来像这样:

TestClass.class
TestClass$SomeOtherInnerClass.class 

My problem is that defineClass() fails to load the TestClass$SomeOtherInnerClass. 我的问题是defineClass()无法加载TestClass $ SomeOtherInnerClass。 If this class is loaded before the actual TestClass i get this: 如果这个类在实际的TestClass之前加载我得到这个:

java.lang.NoClassDefFoundError: TestClass

I also tried to load the TestClass.class first but then im getting this error: 我还尝试首先加载TestClass.class,但后来我得到这个错误:

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

Is there something i'm doing wrong? 有什么我做错了吗?

I looks like you may not be overriding ClassLoader.findClass() . 我看起来你可能没有重写ClassLoader.findClass() Without doing that, the ClassLoader you are extending does not know how to find these classes. 如果不这样做,您正在扩展的ClassLoader不知道如何找到这些类。

Override that function with something that simply looks up in a private static Map<String, Class<?>> for the class. 使用简单查找private static Map<String, Class<?>>private static Map<String, Class<?>>来覆盖该函数。 As you load each class, put it into that map. 在加载每个类时,将其放入该映射中。

The difficulty will be in loading classes in the correct order, as your current implementation will not allow you to jump back to searching the Zip and calling defineClass() from your new findClass() method. 难点在于以正确的顺序加载类,因为您当前的实现将不允许您跳回到搜索Zip并从新的findClass()方法调用defineClass()

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM