我有一个使用内置Eclipse“编译”任务编译的应用程序。然后我决定将构建过程移动到Ant的javac
中,结果变成了较小的文件。
后来我发现将调试级别调整为"vars,lines,source"
我可以嵌入与Eclipse相同的调试信息,并且在很多情况下文件保持完全相同的大小但内部布局不同。因此,我无法使用md5sum签名来确定它们是否完全相同。
除了调试信息之外,2个所谓的相等文件获得不同内部布局或大小的原因是什么?
如何比较已编译的.class文件?
答案 0 :(得分:3)
对于诸如常量池条目的顺序(基本上所有符号信息)以及每个字段/方法/类的属性之类的内容,这不是必需的顺序。不同的编译器可以按照他们想要的顺序自由写出。
您可以比较编译的类,但您需要深入研究类文件结构并解析它。有像这样的图书馆,比如BCEL或ASM,但我并不是100%确定他们会帮助你做你想做的事。
答案 1 :(得分:2)
ASM Eclipse plugin中有一个字节码比较器。您选择两个类,右键单击,并与比较/相互字节码。
答案 2 :(得分:2)
需要注意的一点是Eclipse不使用javac。 Eclipse有自己的编译器the JDT,因此生成的.class文件的差异并不让我感到惊讶。我希望它们不是逐字的,因为它们是不同的编译器。
由于它们的不同,存在使用javac而不是JDT编译的代码,反之亦然。通常我已经看到,在大量使用泛型的情况下,两者的差异变得明显
答案 3 :(得分:1)
最重要的是,局部变量的堆栈槽可以任意排列,而不会改变代码的语义。所以基本上,你不能在没有解析和规范化它们的情况下比较编译的类文件 - 需要付出很多努力。
你为什么要这样做呢?
答案 4 :(得分:1)
我在使用文件大小作为安全性的系统上工作。如果.class文件的大小发生变化,则不会授予该类特定权限。
通常这很容易解决,但我们对环境有相当完全的控制,所以它实际上非常实用。
无论如何,只要重新编译被监视的类,我们就必须重新计算大小。
另一件事 - 编译文件时会生成一个特殊的键编号。我对此并不了解,但它经常阻止课程一起工作。我相信程序是,编译A类并保存它(称之为a1)。再次编译类a(a2)。针对类a2编译类b。尝试针对a1运行b。我相信在这种情况下它会在运行时失败。
如果您可以了解有关该密钥编号的更多信息,它可能会为您提供您所需的信息。
答案 5 :(得分:1)
对于comparisson,您可以反编译您的类文件并使用生成的源进行播放。请参阅this。
答案 6 :(得分:0)
Eclipse是否正在使用一些工具来协助在调试器中运行?
答案 7 :(得分:0)
最终使用的配置可能会有所不同。假设他们使用相同版本的Java,则有许多选项可用于编译配置(JDK合规性,类文件兼容性和一系列调试信息选项)。