ClassFormatError: Неизвестный тег константы в классе XY

У меня есть часть кода, в которой я пытаюсь загрузить класс во время выполнения. Код не все самозаписывается, поэтому у меня есть некоторые проблемы с пониманием ошибки, которая всегда появляется после компиляции.

Здесь код:

private Class findClass(String s)
        throws ClassNotFoundException
    {
        URL url = getResource("AP.class");
        if(url == null)
        {
            throw new ClassNotFoundException(s);
        }
        inputstream = null;
        Class classToRead;
        try
        {
            inputstream = url.openStream();
            byte abyte0[] = readClass(inputstream);
            classToRead= defineClass(s, abyte0, 0, abyte0.length);
        }
        catch(IOException ioexception)
        {
            throw new ClassNotFoundException(s);
        }
        if(inputstream != null)
        {
            try
            {
                inputstream.close();
            }
            catch(Exception exception1) { }
        }
        return classToRead;
    }

Ошибка появляется в методе defineClass.

Ошибка stacktrace:

Exception in thread "main" java.lang.ClassFormatError: Unknown constant tag 63 in class file AP
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at c.findClass(c.java:100)
    at c.loadClass(c.java:56)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at c.a(c.java:20)
    at mainOpenClass.main(lol.java:13)

Теперь мои вопросы: Может быть, что-то не так с кодом? Возможно ли, что AP.class поврежден? Что означает ошибка?

Я надеюсь, что кто-нибудь может помочь мне с моей проблемой, потому что поиск в Интернете действительно не помог в этом случае.

Ответ 1

Код, который вы написали, в порядке. Проблема в том, что AP.class является поврежденным файлом класса - следовательно, ClassFormatError.

Сама ошибка означает, что он не смог правильно декодировать постоянный пул, раздел структуры файла класса, который очень похож на таблицу символов. См. и раздел 4.4 спецификации виртуальной машины Java:

Инструкции виртуальной машины Java не зависят от среды выполнения классов, интерфейсов, экземпляров классов или массивов. Вместо этого инструкции относятся к символической информации в таблице constant_pool.

Все записи constant_pool имеют следующий общий формат:

cp_info {
    u1 tag;
    u1 info[];
}

Каждый элемент таблицы constant_pool должен начинаться с 1-байтового тега, указывающего вид записи cp_info. Содержимое информационного массива зависит от значения тега. Действующие теги и их значения перечислены в Таблица 4.3. За каждым байтом тега должны следовать два или более байта, содержащие информацию о конкретной константе. Формат дополнительной информации зависит от значения тега.

Итак, сама ошибка говорит вам, что класс имеет постоянную запись в таблице пула с недопустимым тегом, а именно 63. Проверка, указанная выше в таблице 4.3, действительно, , это не соответствует документированному типу cp_info entry.

Попробуйте перезагрузить AP.class. Учитывая неясные имена (AP, а также c из трассировки стека), я собираюсь предположить, что вы пытаетесь использовать некоторый обфускационный код. Проверьте не только то, что код, с которым вы пытаетесь справиться, не защищен каким-то типом шифрования, но также и то, что любая препроцессия, которую вы выполняете (например, деобфускация), не повреждает данные.

Ответ 2

Ответы на ваши вопросы:

  • Нет

  • Да

  • Из Java Doc Брошено, когда виртуальная машина Java пытается прочитайте файл класса и определите, что файл неверен или иначе не может быть интерпретирован как файл класса.