首页 > 解决方案 > 当其他参数相同时,AspectJ 生成两个不同的字节码(使用 Java)

问题描述

pom.xml 中维护的以下版本:aspectj 版本:1.8.2 aspectj maven 插件:1.7 java 版本:1.7

在每次编译和aspectj编织之后,生成的字节码都是不同的。(这是编译时方面的编织)。

预期,如果没有任何变化——来自 java 编译器、maven、aspectj运行时库等——生成的字节码应该总是相同的。

如果排除aspectj,则生成的字节码相同。

有什么帮助吗?

解释:假设我的项目生成了一个名为 -amodule.jar 的 jar 文件。

从两个连续编译中取出两个jar文件,我在两个地方提取。然后我为每个类文件生成了 SHA1 密钥,并比较了两个 SHA1 密钥列表,并为许多类文件找到了不同的密钥。现在,显示 SHA1 密钥差异的 java 类文件被反编译成 java 程序。反编译的java程序差异主要可以描述为两类(a)try-catch块的随机移位或位移,catch块内的异常变量重命名;(b) 在某些情况下无法翻译成 java 程序并在生成的 java 程序中保留原始字节码。

由于反编译器效率低下,生成的 java 程序可能有缺陷。但是同一类文件在两次连续编译中使用不同的SHA1 key,就是不同字节码的证明。

当然,上述差异只有在包含 Aspectj 时才会发生(在 java 编译命令行中使用 -Daspect.skip=false)。如果排除 Aspects,SHA1 密钥比较报告显示没有差异。

标签: java

解决方案


您似乎在说字节码本身(不仅仅是 .class 文件)似乎不同。这可以通过 Aspectj 编织器不是完全确定的来解释。例如,如果它在编译过程的某些部分使用了哈希表,并且哈希键具有身份哈希码,那么哈希表数据结构的迭代可能会以不同的顺序从一个编译到下一个编译访问元素。这可能会导致生成的字节码、常量池等存在差异。

如果这是问题的原因,则可能没有实际的解决方案。


关于证据。如果我理解正确,您看到的差异实际上是“.class”文件中的差异;即他们有不同的SHA-1 哈希。

反编译的java程序差异主要可以描述为两类(a)try-catch块的随机移位或位移,catch块内的异常变量重命名;

您在反编译代码中看到的一些差异可能是由于在反编译器中使用了哈希表。这并不是字节码差异的明确证据。

在某些情况下,无法翻译成 java 程序并将原始字节码保留在生成的 java 程序中。

这不是任何证据。反编译的代码无法编译是很常见的。请注意,您正在尝试反编译/重新编译已“编织”的代码,这可能会使反编译器感到困惑。

您可能应该使用javap -c或对字节码进行取证分析,以确定“.class”文件的真正差异是什么。


推荐阅读