Search code examples
javamicronautbyte-buddy

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


I'm using Micronaut 3.0 and Byte Buddy 1.12.6, Groovy for testing.

The problem occurs when I'm running whole package of tests at once in IntelliJ (doesn't have to be whole package, more than 1 test class is enough).

With every test class executed, it is creating +1 Transform for each class that is matched by agent.

First test class executed:

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

Second test class executed:

[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]

Third test class executed:

[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]

etc.

Example test class

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

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

}

My agent 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());
    }

}

Advice

public class LoggingAdvice {

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

Solution

  • I assume that the agent is installed multiple times, likely once per test. You can deregister or even reset an installed agent, the returned ResettableClassFileTransformer offers methods for this. Alternatively, check if tour agent is already active on the current VM and avoid its reregistration.