Byte Buddy 在每次测试 class 执行后创建 +1 TRANSFORM

Byte Buddy is creating +1 TRANSFORM after every test class execution

我正在使用 Micronaut 3.0 和 Byte Buddy 1.12.6,Groovy 进行测试。

当我在 IntelliJ 中一次 运行 整个测试包时出现问题(不必是整个包,超过 1 个测试 class 就足够了)。

执行每个测试 class 时,它会为代理匹配的每个 class 创建 +1 转换。

执行的第一个测试class:

[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]

第二个测试class执行:

[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]
[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]

第三次测试class执行:

[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]
[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]
[Byte Buddy] TRANSFORM com.class [jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27, unnamed module @87a85e1, Thread[Test worker,5,main], loaded=true]

等等

示例测试class

@MicronautTest(transactional = false, environments = "db")
@Stepwise
@Slf4j
class TestClass with Specification {

    def "test method"() {
    .....
    }

}

我的经纪人class:

@Context
public class LoggingAgent {

    @PostConstruct
    private void premain() {
        new AgentBuilder.Default()
                .disableClassFormatChanges()
                .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
                .with(AgentBuilder.InstallationListener.StreamWriting.toSystemError())
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .type(isSubTypeOf(Test.class).and(not(isAbstract())))
                .transform((builder, typeDescription, classLoader, module) -> builder.visit(Advice.to(LoggingAdvice.class).on(isMethod())))
                .installOn(ByteBuddyAgent.install());
    }

}

建议

public class LoggingAdvice {

    @Advice.OnMethodEnter
    public static void intercept(@Advice.Origin Method method, @Advice.AllArguments Object[] args) throws Exception {
    .....
    }
}

我假设代理已安装多次,可能每次测试一次。您可以取消注册甚至重置已安装的代理,返回的 ResettableClassFileTransformer 为此提供了方法。或者,检查旅行代理是否已在当前 VM 上激活并避免其重新注册。