Search code examples
instrumentationmaven-surefire-pluginbyte-buddyjavaagents

accessing test classes from javaagent using maven-surefire


I am trying to run an analysis that would capture the values of the locator when running selenium test. Having a large number of projects and versions to test, I want to avoid directly modifying the project files whatsoever, hence, I resorted to the use of a javaagent (with ByteBuddy). The idea is to instrument the test classes so they will get me the information I need. Hence, in the pom.xml of the project I am analyzing i had to setup the surefire-plugin as follow

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M1</version>
            <configuration>
                <argLine>@{argLine} -javaagent:\path\to\my\agent.jar</argLine>
                <forkCount>0</forkCount>
            </configuration>
          </plugin>

The argLine field allows me to attach the agent to the surefire process and the forkCount forces surefire to only use one JVM which should allow me to have a visibility on all the classes that are loaded (I think).

As for the agent, I have the premain method as follow

public static void premain(final String agentArgs,
                           final Instrumentation inst) {
    System.out.println("Starting to collect metrics");

    new AgentBuilder.Default()
            .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
            .type(ElementMatchers.any())
            .transform(new LocatorReporterTransformer())
            .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
            .installOn(inst);
}

I used the ElementMatchers.any() to be sure to be able to see all the classes that were intercepted by my agent. In the LocatorReporterTransormer class, i have the method transform(...) as follow

@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
                                        TypeDescription typeDescription,
                                        ClassLoader classLoader,
                                        JavaModule javaModule) {

    System.out.println(typeDescription.getName());
    return builder;
}

My goal was to capture some of the classes from my tests, but it seems they are never loaded in the JVM, which is weird to me. Thus, my question is: How can I safeley add a javaagent to surefire and make sure it can access all the classes? Is there a way for the javaagent to capture all the subprocess from a target?


Solution

  • The classes were not all visible because more than one process was executing. It seems that the forkCount = 0 d did not do the trick. One solution is to actually attach the agent on the maven process using the MAVEN_OPTS and then use fockMode = never. Here is the implementation that works in my case:

    set "MAVEN_OPTS=-javaagent:\path\to\agent.jar"
    mvn test -DforkMode=never