我有一个使用内置 Eclipse“编译”任务编译的应用程序。然后我决定将构建过程移到 Ant 中javac,结果文件变小了。
后来我发现将调试级别调整为"vars,lines,source"可以嵌入与 Eclipse 相同的调试信息,并且在很多情况下,文件的大小完全相同,但内部布局不同。因此,我无法使用 md5sum 签名来确定它们是否完全相同。
除了调试信息之外,两个据称相等的文件获得不同的内部布局或大小的原因可能是什么?
以及如何比较已编译的 .class 文件?
我有一个使用内置 Eclipse“编译”任务编译的应用程序。然后我决定将构建过程移到 Ant 中javac,结果文件变小了。
后来我发现将调试级别调整为"vars,lines,source"可以嵌入与 Eclipse 相同的调试信息,并且在很多情况下,文件的大小完全相同,但内部布局不同。因此,我无法使用 md5sum 签名来确定它们是否完全相同。
除了调试信息之外,两个据称相等的文件获得不同的内部布局或大小的原因可能是什么?
以及如何比较已编译的 .class 文件?
ASM Eclipse插件中有一个字节码比较器。您选择两个类,单击鼠标右键,然后进行比较/彼此字节码。
需要注意的重要一点是 Eclipse 不使用 javac。Eclipse 有自己的编译器JDT,因此生成的 .class 文件中的差异并不让我感到惊讶。我希望它们不是逐字记录,因为它们是不同的编译器。
由于它们的差异,存在使用 javac 而不是 JDT 编译的代码,反之亦然。通常,在大量使用泛型的情况下,我已经看到两者的差异变得明显
最重要的是,在不改变代码语义的情况下,局部变量的栈槽可以任意排列。所以基本上,如果不解析和规范化它们,你就无法比较编译的类文件 - 相当多的努力。
你为什么要这样做呢?
正如 Michale B 所说,它可以是任意的。
我在使用文件大小作为安全性的系统上工作。如果 .class 文件的大小发生变化,则不会授予该类某些权限。
通常这很容易解决,但我们可以完全控制环境,所以它实际上非常实用。
无论如何,每当重新编译所监视的类时,我们似乎都必须重新计算大小。
另一件事——编译文件时会生成一个特殊的密钥编号。我对此了解不多,但它经常阻止类一起工作。我相信程序是,编译A类并保存它(称之为a1)。再次编译 a 类(a2)。针对类 a2 编译类 b。尝试对 a1 运行 b。我相信在这种情况下它会在运行时失败。
如果您可以了解有关该密钥号码的更多信息,它可能会为您提供所需的信息。
对于比较,您可以反编译您的类文件并使用生成的源代码。看到这个。
Eclipse 是否在做一些检测来帮助在调试器中运行?
最终,所使用的配置可能会有所不同。假设他们使用相同版本的 Java,则有许多选项可用于编译配置(JDK 合规性、类文件兼容性和大量调试信息选项)。