[英]How to instrument/rebase inner classes with Byte Buddy?
I would like to create a plug-in wrapper to embed a Java code that will let me enable/disable methods annotated with JUnit5 Before* and After* annotations at runtime as well as handle in similar manner JUnit5 extensions (the ExtendWith annotation).我想创建一个插件包装器来嵌入 Java 代码,它可以让我在运行时启用/禁用使用 JUnit5 Before* 和 After* 注释注释的方法,并以类似的方式处理 JUnit5 扩展(ExtendWith 注释)。
I chose ByteBuddy as primary instrumentation library.我选择 ByteBuddy 作为主要的仪器库。
I created a github repo here: https://github.com/azewiusz/bytebuddy_examples where I describe the idea in more detail.我在这里创建了一个 github 存储库: https ://github.com/azewiusz/bytebuddy_examples 在这里我更详细地描述了这个想法。
The problem is that I cannot get instrumentation working for inner classes.问题是我无法让仪器为内部类工作。 I keep getting two exceptions:
我不断收到两个例外:
Caused by: java.lang.IllegalStateException: Failed to invoke proxy for public abstract java.lang.reflect.AnnotatedElement net.bytebuddy.description.method.MethodDescription$InDefinedShape$AbstractBase$Executable.getAnnotatedReceiverType(java.lang.Object)
原因:java.lang.IllegalStateException:无法为公共抽象 java.lang.reflect.AnnotatedElement net.bytebuddy.description.method.MethodDescription$InDefinedShape$AbstractBase$Executable.getAnnotatedReceiverType(java.lang.Object)调用代理
preceded by之前
Caused by: java.lang.IncompatibleClassChangeError tests.TestSetWithInnerClasses and tests.TestSetWithInnerClasses$HelperTestFilteredOutExtendWithInnerClass disagree on InnerClasses attribute
引起:java.lang.IncompatibleClassChangeError tests.TestSetWithInnerClasses 和 tests.TestSetWithInnerClasses$HelperTestFilteredOutExtendWithInnerClass 不同意 InnerClasses 属性
A test class that reproduces is here: https://github.com/azewiusz/bytebuddy_examples/blob/master/src/test/java/tests/CoreInstrumentationTest.java重现的测试类在这里: https ://github.com/azewiusz/bytebuddy_examples/blob/master/src/test/java/tests/CoreInstrumentationTest.java
-> Look there for test2 -> 在那里寻找 test2
It fails at this transformation:它在这个转换中失败了:
final Class strippedOffExtendWithAnnotation = filterOutJUnit5ExtendWithAnnotation(
testClass, classLoader );
Class beforeAll = stagedTypeTransform( strippedOffExtendWithAnnotation,
new ByteBuddy().rebase( strippedOffExtendWithAnnotation,
ClassFileLocator.ForClassLoader.of( classLoader ) )
.name( testClass.getName() + "BeforeAll" )
.method( ElementMatchers
.isAnnotatedWith( BeforeAll.class ) )
.intercept( MethodDelegation.to( InterceptorForBeforeAllAnnotation.class ) ).make() );
I found following that seem to refer to similar problem:我发现以下似乎是指类似的问题:
But haven't found yet an exact solution.但还没有找到确切的解决方案。
Instrumenting inner classes is tricky.检测内部类很棘手。 Java classes contain so-called inner class attributes that describe Java class properties that compiled Java classes cannot represent.
Java 类包含所谓的内部类属性,这些属性描述了编译后的 Java 类无法表示的 Java 类属性。 For example, a compiled Java class cannot be private , but you would still want to see this modifier for the inner class when using reflection.
例如,已编译的 Java 类不能是private ,但在使用反射时您仍希望看到内部类的此修饰符。
You can consider to make your new class a top-level class by using topLevelType()
in the DSL.您可以考虑通过在 DSL 中使用
topLevelType()
使您的新类成为顶级类。 You should also consider noNestMate()
to avoid clashes there.您还应该考虑
noNestMate()
以避免在那里发生冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.