Пользовательский загрузчик классов Java и внутренние классы

У меня есть этот метод (в моем собственном загрузчике классов), который загружает классы из 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);
    }
}

Почтовый индекс, который я пытаюсь загрузить, выглядит так:

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 

Есть ли что-то, что я делаю неправильно?


person justme_    schedule 25.03.2011    source источник
comment
у меня та же проблема, как я могу загрузить внутренние классы? мой класс A загружается правильно, но мои классы A $ b1 нет... не могу найти способ загрузить внутренние классы... у вас есть прогресс?   -  person jrey    schedule 13.04.2011


Ответы (2)


Похоже, вы не переопределяете ClassLoader.findClass(). Без этого ClassLoader, который вы расширяете, не знает, как найти эти классы.

Переопределите эту функцию чем-то, что просто ищет класс в private static Map<String, Class<?>>. Когда вы загружаете каждый класс, помещайте его в эту карту.

Трудность будет заключаться в загрузке классов в правильном порядке, так как ваша текущая реализация не позволит вам вернуться к поиску Zip и вызову defineClass() из вашего нового метода findClass().

person Jonathan    schedule 25.03.2011
comment
Мой текущий код выглядит так: ссылка Но моя проблема все еще существует, если я попытаюсь Сначала загрузите TestClass, он выдает ошибку, потому что не может найти внутренний класс (поскольку он еще не определен). Я не знаю, как это решить:/ - person justme_; 25.03.2011

Есть по крайней мере одна ошибка в том, что вы (обязательно) не полностью читаете буфер (и ZipEntry.getSize может вернуть -1).

person Tom Hawtin - tackline    schedule 25.03.2011