AspectJ 在其他参数相同时生成两种不同的字节码(与 Java 一起),

huangapple 未分类评论40阅读模式
英文:

AspectJ generates two different byte codes (with Java) when other parameters are same

问题

以下是翻译好的内容:

在 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 密钥,这是不同字节码的证明。

当然,上述提到的差异仅在包含 Aspectj 时发生(在 Java 编译命令行中使用 -Daspect.skip=false)。如果排除切面,则 SHA1 密钥比较报告不会显示差异。

英文:

Following versions maintained in pom.xml :
aspectj version : 1.8.2
aspectj maven plugin : 1.7
java version : 1.7

After every compilation and aspectj weaving, generated byte code is different. (It is compilation time aspect weaving).

Expected, if nothing changes - from java compiler, maven, aspectj runtime library etc - generated byte code always should be same.

If aspectj is excluded, then generated byte code is same.

Any help?

Explanation :
Say my project generates a jar file named - amodule.jar.

Taking two jar files from two consecutive compilations, I extracted in two places. Then I generated SHA1 keys for every class file and compared two SHA1 key lists and found different keys for many class files. Now java class files, showing differences in SHA1 key, were decompiled into java programs. Decompiled java program differences may be described mainly in two categories (a) shifting or displacement of try - catch block randomly and renaming exception variables within catch block; (b) In some cases not able to translate into java programs and keeping the original byte code in generated java programs.

Generated java programs may be defective due to inefficiency of decompiler. But different SHA1 key for the same class file in two consecutive compilation is the proof of different byte code.

Of course above mentioned difference happens only when Aspectj is included (-Daspect.skip=false used in java compilation command line). If Aspects is excluded, SHA1 key comparison report shows no difference.

答案1

得分: 0

你似乎在说字节码本身(而不仅仅是.class文件)似乎是不同的。这可能可以解释为Aspectj织入器不是完全确定性的原因。例如,如果在编译过程的某个部分使用了哈希表,并且哈希键具有标识哈希码,那么哈希表数据结构的迭代可能会导致不同编译之间访问元素的顺序不同。这可能会导致生成的字节码、常量池等方面的差异。

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

关于证据。如果我理解你的意思正确,你看到的差异实际上是".class"文件的差异;即它们具有不同的SHA-1哈希值。

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

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

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

这并不能证明任何事情。反编译的代码通常无法编译。请注意,你正在尝试反编译/重新编译已经被"织入"的代码,这可能会混淆反编译器。

你应该考虑使用javap -c或对字节码进行取证分析,以确定".class"文件的差异究竟是什么。

英文:

You seem to be saying that that the bytecodes themselves (not just the .class files) appear to be different. This could be explained by the Aspectj weaver not being entirely deterministic. For example, if it used hash tables in some part of the compilation processes, and the hash keys have identity hashcodes, then iteration of the hash table data structure is liable to visit elements in a different order from one compilation to the next. This could cause differences in the generated bytecodes, constants pool and so on.

If this is the cause of the problem there is probably no practical solution.


Concerning the evidence. If I understand you correctly, the differences you are seeing are actually differences in the ".class" files; i.e. they have different SHA-1 hashes.

> Decompiled java program differences may be described mainly in two categories (a) shifting or displacement of try - catch block randomly and renaming exception variables within catch block;

It is possible that some of these differences that you are seeing in decompiled code are due to use of hash tables in the decompiler. This is not definitively evidence of bytecode differences.

> In some cases not able to translate into java programs and keeping the original byte code in generated java programs.

This is not evidence of anything. It is common for decompiled code to not be compileable. And note that you are attempting to decompile / recompile code that has been "woven", which may be confusing the decompiler.

You should probably be using javap -c or doing a forensic analysis of the byte code to determine what the ".class" file differences really are.

huangapple
  • 本文由 发表于 2020年4月4日 15:23:35
  • 转载请务必保留本文链接:https://java.coder-hub.com/61024968.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定