简体   繁体   English

如何使用 Byte Buddy 检测/重新定义内部类?

[英]How to instrument/rebase inner classes with Byte Buddy?

Goal目标

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 在这里我更详细地描述了这个想法。

Question问题

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM