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 上激活并避免其重新注册。
我正在使用 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 上激活并避免其重新注册。