java ClassFormatError:XY 类中的未知常量标记

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12333849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:27:52  来源:igfitidea点击:

ClassFormatError: Unknown constant tag in class XY

java

提问by Mister004

I have a piece of code in which I try to load a class during runtime. The code is not all selfwritten so I have some problems understanding the error which always appers after compiling.

我有一段代码,我尝试在运行时加载一个类。代码并非都是自写的,所以我在理解编译后总是出现的错误时遇到了一些问题。

Here the code:

这里的代码:

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;
    }

The error appears at the defineClass method.

该错误出现在defineClass 方法中。

Error 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)

My questions now are: Is maybe anything wrong with the code? Is it possible that the AP.class is damaged? What does the error really mean?

我现在的问题是:代码可能有什么问题吗?有没有可能是AP.class损坏了?错误的真正含义是什么?

I hope anybody can help me with my problem because searching the internet didn't really help in that case.

我希望任何人都可以帮助我解决我的问题,因为在这种情况下搜索互联网并没有真正的帮助。

回答by oldrinb

The code you've written yourself is fine. The problem is that AP.classis a damaged class file -- hence the ClassFormatError.

你自己写的代码没问题。问题是这AP.class是一个损坏的类文件 - 因此ClassFormatError.

The error itself means that it failed to correctly decode the constant pool, a section of the class file structure that is much like a symbol table. See §4.4 of the Java Virtual Machine Specification:

错误本身意味着它未能正确解码常量池,这是类文件结构的一部分,很像符号表。请参阅Java 虚拟机规范的 §4.4

Java virtual machine instructions do not rely on the runtime layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pooltable.

All constant_pooltable entries have the following general format:

cp_info {
    u1 tag;
    u1 info[];
}

Each item in the constant_pooltable must begin with a 1-byte tag indicating the kind of cp_infoentry. The contents of the info array vary with the value of tag. The valid tags and their values are listed in Table 4.3. Each tag byte must be followed by two or more bytes giving information about the specific constant. The format of the additional information varies with the tag value.

Java 虚拟机指令不依赖于类、接口、类实例或数组的运行时布局。相反,指令引用constant_pool表中的符号信息。

所有constant_pool表条目都具有以下通用格式:

cp_info {
    u1 tag;
    u1 info[];
}

constant_pool表中的每一项都必须以指示cp_info条目类型的 1 字节标记开始。info 数组的内容随 tag 的值而变化。表 4.3中列出了有效标签及其值。每个标记字节后面必须跟两个或更多字节,以提供有关特定常量的信息。附加信息的格式因标签值而异。

So, the error itself is telling you that the class has a constant pool table entry with an invalid tag, namely 63. Verifying with Table 4.3 mentioned above, indeed, this does not correspond to any documented kind of cp_infoentry.

因此,错误本身告诉您该类有一个带有无效标记的常量池表条目,即63. 用上面提到的表 4.3 进行验证,确实,这并不对应于任何记录在案的cp_info条目

Try to re-download AP.class. Given the obscure names (AP, as well as cfrom the stack trace), I'm going to assume you're trying to use some obfuscated code. Verify not only that the code you're trying to deal with is not further protected by some sort of encryption, but also that any preprocessing you do (e.g. deobfuscation) does not corrupt the data.

重新下载试试AP.class。鉴于晦涩的名称(AP,以及c来自堆栈跟踪),我将假设您正在尝试使用一些混淆代码。不仅要验证您尝试处理的代码没有受到某种加密的进一步保护,而且还要验证您所做的任何预处理(例如反混淆)不会破坏数据。

回答by Sergii Zagriichuk

Answers to your questions:

回答您的问题:

  1. No

  2. Yes

  3. From Java DocThrown when the Java Virtual Machine attempts to read a class file and determines that the file is malformed or otherwise cannot be interpreted as a class file.

  1. 是的

  2. 从 Java Doc当 Java 虚拟机尝试读取类文件并确定该文件格式错误或无法解释为类文件时抛出。