Java 使用 AspectJ 的字节码错误
Java bytecode error using AspectJ
我正在尝试使用 AspectJ 修改某些代码的工作方式。 aspectJ 代码的形式为 (Profiler.java):
public aspect Profiler {
pointcut beforeMethod(): !within(Profiler);
before(): beforeMethod() { /* Do something */ }
pointcut afterMethod(): !within(Profiler);
after(): afterMethod() { /* Do something */}
}
我现在正在尝试 运行 以下代码 (Hello.java):
public class Hello {
public static void main(String args[]) {
for (int i = 0; i < 100; i++) {
a(i);
}
System.out.println("Hello");
}
public static void a(int x) {
for (int i = 0; i < 10; i++) {
b();
}
}
public static void b() {
int j = 1;
for (int i = 0; i < 10; i++) {
j++;
}
}
}
使用 ajc 编译器编译 Hello.java 和 Profiler.java 给了我预期的结果。但是当我使用 ajc 将 Profiler.java 编译为 jar 文件并尝试使用 javaagent 时,它给出了一个字节码错误:
Exception in thread "main" java.lang.VerifyError: Bad <init> method call from after the start of a try block
Exception Details:
Location:
Hello.<init>()V @55: invokespecial
Reason:
Error exists in the bytecode
Bytecode:
0000000: 2ab2 0065 0101 b800 2e3a 05b8 0034 1905
0000010: b200 65b6 0038 00a7 0013 3a06 b800 3419
0000020: 05b2 0065 b600 3b19 06bf 00b8 0034 1905
0000030: b200 65b6 003b 00b7 0001 b200 622a 2ab8
0000040: 002e 4eb8 0034 2db2 0062 b600 38b2 0028
0000050: 2a2a b800 2e4c b800 342b b200 28b6 0038
0000060: a700 104d b800 342b b200 28b6 003b 2cbf
0000070: b800 342b b200 28b6 003b a700 123a 04b8
0000080: 0034 2db2 0062 b600 3b19 04bf b800 342d
0000090: b200 62b6 003b b1
知道问题出在哪里吗?
我认为您遇到了 https://bugs.eclipse.org/bugs/show_bug.cgi?id=443477 的变体,与预初始化连接点的编织有关。第一步我会说尝试使用最新的 AspectJ 版本(你没有提到你使用的是什么版本)。但是,这可能无法解决问题,因为 443477 的修复与您未使用的 cflow 相关。如果它仍然发生,我会说在 bugs.eclipse.org 上针对 AspectJ 提出一个错误。你确实有相当广泛的切入点 - 我们真的不建议编写不使用 kinded
组件(call/execution/get/set/etc)的切入点 - 如果没有它们,你将与其他所有东西一起击中那些预初始化连接点。您可以通过调整切入点来排除预初始化,这可能是一种解决方法。
我正在尝试使用 AspectJ 修改某些代码的工作方式。 aspectJ 代码的形式为 (Profiler.java):
public aspect Profiler {
pointcut beforeMethod(): !within(Profiler);
before(): beforeMethod() { /* Do something */ }
pointcut afterMethod(): !within(Profiler);
after(): afterMethod() { /* Do something */}
}
我现在正在尝试 运行 以下代码 (Hello.java):
public class Hello {
public static void main(String args[]) {
for (int i = 0; i < 100; i++) {
a(i);
}
System.out.println("Hello");
}
public static void a(int x) {
for (int i = 0; i < 10; i++) {
b();
}
}
public static void b() {
int j = 1;
for (int i = 0; i < 10; i++) {
j++;
}
}
}
使用 ajc 编译器编译 Hello.java 和 Profiler.java 给了我预期的结果。但是当我使用 ajc 将 Profiler.java 编译为 jar 文件并尝试使用 javaagent 时,它给出了一个字节码错误:
Exception in thread "main" java.lang.VerifyError: Bad <init> method call from after the start of a try block
Exception Details:
Location:
Hello.<init>()V @55: invokespecial
Reason:
Error exists in the bytecode
Bytecode:
0000000: 2ab2 0065 0101 b800 2e3a 05b8 0034 1905
0000010: b200 65b6 0038 00a7 0013 3a06 b800 3419
0000020: 05b2 0065 b600 3b19 06bf 00b8 0034 1905
0000030: b200 65b6 003b 00b7 0001 b200 622a 2ab8
0000040: 002e 4eb8 0034 2db2 0062 b600 38b2 0028
0000050: 2a2a b800 2e4c b800 342b b200 28b6 0038
0000060: a700 104d b800 342b b200 28b6 003b 2cbf
0000070: b800 342b b200 28b6 003b a700 123a 04b8
0000080: 0034 2db2 0062 b600 3b19 04bf b800 342d
0000090: b200 62b6 003b b1
知道问题出在哪里吗?
我认为您遇到了 https://bugs.eclipse.org/bugs/show_bug.cgi?id=443477 的变体,与预初始化连接点的编织有关。第一步我会说尝试使用最新的 AspectJ 版本(你没有提到你使用的是什么版本)。但是,这可能无法解决问题,因为 443477 的修复与您未使用的 cflow 相关。如果它仍然发生,我会说在 bugs.eclipse.org 上针对 AspectJ 提出一个错误。你确实有相当广泛的切入点 - 我们真的不建议编写不使用 kinded
组件(call/execution/get/set/etc)的切入点 - 如果没有它们,你将与其他所有东西一起击中那些预初始化连接点。您可以通过调整切入点来排除预初始化,这可能是一种解决方法。