问题描述
给定 Sample.someMethod(...)
和 InvocationHandler decoration
,我想创建一个动态子类,用
someMethod
someMethod(...) {
decoration.invoke(...);
super.someMethod(...);
}
我的代码如下:
Class<? extends Sample> dynamicSubclass = new ByteBuddy()
.subclass(Sample.class)
.method(ElementMatchers.named("someMethod"))
.intercept(new Implementation.Compound(
InvocationHandlerAdapter.of(decoration),SuperMethodCall.INSTANCE))
.make()
.load(Sample.class.getClassLoader()) // line 42
.getLoaded();
...它导致以下异常:
java.lang.VerifyError: Expecting a stack map frame
Exception Details:
Location:
pl/morgwai/sample/pojo/ByteBuddySample$Sample$ByteBuddy$PXUw8Sz7.someMethod(I)Ljava/lang/String; @27: aload_0
Reason:
Error exists in the bytecode
Bytecode:
0000000: b200 0a2a b200 0e04 bd00 1059 031b b800
0000010: 1653 b900 1c04 00c0 001e b02a 1bb7 0020
0000020: b0
at java.base/java.lang.class.getDeclaredFields0(Native Method)
at java.base/java.lang.class.privateGetDeclaredFields(Class.java:3061)
at java.base/java.lang.class.getDeclaredField(Class.java:2409)
at net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField.onLoad(LoadedTypeInitializer.java:122)
at net.bytebuddy.implementation.LoadedTypeInitializer$Compound.onLoad(LoadedTypeInitializer.java:192)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:102)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6292)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6281)
at pl.morgwai.sample.pojo.ByteBuddySample.main(ByteBuddySample.java:42)
我做错了什么以及如何解决?
(我使用的是字节伙伴 1.10.22 和 openjdk-11)
谢谢!
更新:
我能够实现
someMethod(...) {
decoration.invoke(...);
}
和
someMethod(...) {
super.someMethod(...);
}
分别执行 .intercept(InvocationHandlerAdapter.of(decoration))
和 .intercept(SuperMethodCall.INSTANCE)
,所以看起来,我没有正确使用 Implementation.Compound
...
更新-2:
我也能达到
someMethod(...) {
super.someMethod(...);
decoration.invoke(...);
}
由
.intercept(SuperMethodCall.INSTANCE.andThen(InvocationHandlerAdapter.of(decoration)))
但我不能反过来实现我需要的顺序,因为 InvocationHandlerAdapter
没有实现 Implementation.Composable
...
解决方法
请explained by Rafael Winterhalter,这是一个无意的遗漏,在下一个版本中InvocationHandlerAdapter
将实施Composable
(commit 已经推送)然后最简单的方法是做
.intercept(InvocationHandlerAdapter.of(decoration).andThen(SuperMethodCall.INSTANCE))