2

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?

animuson
  • 53,861
  • 28
  • 137
  • 147
justme_
  • 645
  • 2
  • 8
  • 11
  • i have the same problem, how i can load the inner classes?, my class A is loaded correctly, but my classes A$b1 no... no find a way to load the inner classes...you had any progress? – jrey Apr 13 '11 at 05:32

2 Answers2

3

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.

Jonathan
  • 13,354
  • 4
  • 36
  • 32
  • My current code looks like this: [link](http://pastebin.com/raw.php?i=ngE2DJK9) But my problem still exists, if i try to load TestClass first it throws error because it cannot find the inner class (as its not yet defined) I don't know how to solve this :/ – justme_ Mar 25 '11 at 20:22
0

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

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305