Custom Java classloader and inner classes

放肆的年华 提交于 2021-01-27 12:51:29

问题


I have this method (in my own classloader) that loads classes from 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:

TestClass.class
TestClass$SomeOtherInnerClass.class 

My problem is that defineClass() fails to load the TestClass$SomeOtherInnerClass. If this class is loaded before the actual TestClass i get this:

java.lang.NoClassDefFoundError: TestClass

I also tried to load the TestClass.class first but then im getting this error:

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

Is there something i'm doing wrong?


回答1:


I looks like you may not be overriding ClassLoader.findClass(). Without doing that, the ClassLoader you are extending does not know how to find these classes.

Override that function with something that simply looks up in a private static Map<String, Class<?>> for the 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.




回答2:


There's at least one bug in that you don't (necessarily) fully read the buffer (and ZipEntry.getSize may return -1).



来源:https://stackoverflow.com/questions/5436410/custom-java-classloader-and-inner-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!