17

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

这里的代码:

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 方法中。

错误堆栈跟踪:

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 是否有可能损坏?错误的真正含义是什么?

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

4

2 回答 2

10

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

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

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

所有constant_pool表格条目都具有以下一般格式:

cp_info {
    u1 tag;
    u1 info[];
}

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

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

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

于 2012-09-08T20:02:41.240 回答
0

回答您的问题:

  1. 是的

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

于 2012-09-08T19:47:02.750 回答