微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 ByteBuddy

如何解决使用 ByteBuddy

给定 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 实施Composablecommit 已经推送)然后最简单的方法是做

.intercept(InvocationHandlerAdapter.of(decoration).andThen(SuperMethodCall.INSTANCE))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。