我有一个使用内置 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 合规性、类文件兼容性和大量调试信息选项)。