javassist 无法编译:异常:堆栈高度不一致 -1
javassist cannot compile: exception: inconsistent stack height -1
我正在尝试使用 javassist
在加载时修改某些测试 classes 的字节码。
这就是我想要做的:
for (CtMethod ctm : ctc.getDeclaredMethods()) {
ctm.instrument(
new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException{
m.replace("{"
+ "try {"
+ "$_ = $proceed($$);"
+ "} catch(Exception e) {"
+ " System.err.println(e); "
+ " }"
+ "}"
);
}
});
}
}
}
ctc:class CtClass 的一个对象:正在加载的 class(它来自我的翻译器实现中的 onLoad 方法)
ctm: class ctc.
上的一个方法
基本上,我正在尝试做一些简单的事情:对于在 class 即时加载中声明的每个方法,我想检测该方法,替换每个 方法调用 在那个方法中,涉及一个 try-catch。
是的,我知道我有函数 addCatch
,但这不能满足我的最终目的,我需要在这里使用表达式编辑器。
这是 class 我正在 运行 测试这个:
public class B {
public double bar(int x) {
System.out.println("Inside B.bar");
return (1 / x);
}
}
我想把这个class改造成:
public class B {
public double bar(int x) {
try {
System.out.println("Inside B.bar");
} catch (Exception e) {
System.err.println(e);
}
return (1 / x);
}
}
(是的,我知道这很奇怪,但我想让它正常工作。
但是,每次尝试时,都会出现以下错误:
javassist.CannotCompileException: ... : inconsistent stack height -1
...
Caused by: javassist.bytecode.BadBytecode: ... inconsistent stack height -1
Expecting a stackmap frame at branch target 30
Exception Details:
Location:
test/Example.main([Ljava/lang/String;)V @21: aload_1
Reason:
Expected stackmap frame at this location.
Bytecode:
0000000: b200 10bb 0016 59b7 0018 bb00 1959 b700
0000010: 1b4d 4c0e 4a2b 2cb6 001c 4aa7 0010 3a05
0000020: b200 2e19 05b6 0031 a700 0329 494c 2b28
0000030: b600 2001 3a04 a700 103a 05b2 002e 1905
0000040: b600 31a7 0003 b1
有人知道这个错误吗?堆叠高度不一致?我查看了 google,但什么也没有。
由于在 ExprEditor.MethodCall.replace(String) 调用中有 Try/Catch 个块导致堆栈错误不一致:
https://issues.jboss.org/browse/JASSIST-210
The tutorial 在第 4.2 节中也提到了这一点 ("It cannot be or contain a try-catch statement.")
这是因为 Try/Catch 机制的复杂性,特别是:
"If an exception is thrown in the try block, then all the values in the stack are popped out."
replace() 函数没有考虑到这一点,因此不会生成适当的字节码。 addCatch() 方法可以。
我正在尝试使用 javassist
在加载时修改某些测试 classes 的字节码。
这就是我想要做的:
for (CtMethod ctm : ctc.getDeclaredMethods()) {
ctm.instrument(
new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException{
m.replace("{"
+ "try {"
+ "$_ = $proceed($$);"
+ "} catch(Exception e) {"
+ " System.err.println(e); "
+ " }"
+ "}"
);
}
});
}
}
}
ctc:class CtClass 的一个对象:正在加载的 class(它来自我的翻译器实现中的 onLoad 方法)
ctm: class ctc.
上的一个方法基本上,我正在尝试做一些简单的事情:对于在 class 即时加载中声明的每个方法,我想检测该方法,替换每个 方法调用 在那个方法中,涉及一个 try-catch。
是的,我知道我有函数 addCatch
,但这不能满足我的最终目的,我需要在这里使用表达式编辑器。
这是 class 我正在 运行 测试这个:
public class B {
public double bar(int x) {
System.out.println("Inside B.bar");
return (1 / x);
}
}
我想把这个class改造成:
public class B {
public double bar(int x) {
try {
System.out.println("Inside B.bar");
} catch (Exception e) {
System.err.println(e);
}
return (1 / x);
}
}
(是的,我知道这很奇怪,但我想让它正常工作。 但是,每次尝试时,都会出现以下错误:
javassist.CannotCompileException: ... : inconsistent stack height -1
...
Caused by: javassist.bytecode.BadBytecode: ... inconsistent stack height -1
Expecting a stackmap frame at branch target 30
Exception Details:
Location:
test/Example.main([Ljava/lang/String;)V @21: aload_1
Reason:
Expected stackmap frame at this location.
Bytecode:
0000000: b200 10bb 0016 59b7 0018 bb00 1959 b700
0000010: 1b4d 4c0e 4a2b 2cb6 001c 4aa7 0010 3a05
0000020: b200 2e19 05b6 0031 a700 0329 494c 2b28
0000030: b600 2001 3a04 a700 103a 05b2 002e 1905
0000040: b600 31a7 0003 b1
有人知道这个错误吗?堆叠高度不一致?我查看了 google,但什么也没有。
由于在 ExprEditor.MethodCall.replace(String) 调用中有 Try/Catch 个块导致堆栈错误不一致:
https://issues.jboss.org/browse/JASSIST-210
The tutorial 在第 4.2 节中也提到了这一点 ("It cannot be or contain a try-catch statement.")
这是因为 Try/Catch 机制的复杂性,特别是:
"If an exception is thrown in the try block, then all the values in the stack are popped out."
replace() 函数没有考虑到这一点,因此不会生成适当的字节码。 addCatch() 方法可以。