Skip to content

parttimenerd/meta-agent

Meta-Agent

Who instruments the instrumenter? This project is a Java agent that instruments Java agents, or specifically, it instruments the ClassFileTransformers of other agents to observe how they transform the bytecode of classes and can also capture native agents with the help of its own.

This is especially useful to check what libraries like Mockito, Dynatrace or async-profiler's method trace do to your classes at runtime.

To run it, build the project with mvn package -DskipTests and run your Java program with the agent:

java -javaagent:target/meta-agent.jar -jar your-program.jar

# or run a Mockito based sample test
mvn package -DskipTests
mvn test -DargLine="-javaagent:target/meta-agent.jar=server"

# or run with an instrumentation handler
mvn -DargLine="-javaagent:target/meta-agent.jar=server,cb=me.bechberger.meta.LoggingInstrumentationHandler" test

The executed MockitoTest looks as follows:

@ExtendWith(MockitoExtension.class)
public class MockitoTest {

  @Mock
  List<String> mockedList;

  @Test
  public void whenNotUseMockAnnotation_thenCorrect() throws InterruptedException {
    mockedList.add("one");
    Mockito.verify(mockedList).add("one");
    assertEquals(0, mockedList.size());

    Mockito.when(mockedList.size()).thenReturn(100);
    assertEquals(100, mockedList.size());

    Thread.sleep(10000000L);
  }
}

If you also want to capture native agents, you can build the native part with

(cd native && make)

and then run with

# on Mac OS
java -agentpath:native/native_agent.dylib -javaagent:target/meta-agent.jar=server -jar your-program.jar
# on Linux
java -agentpath:native/native_agent.so -javaagent:target/meta-agent.jar=server -jar your-program.jar

More on this in the native README.

Opening localhost will show you a list of available commands, most importantly

In our example, we can see via /instrumentators that Mockito uses the org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker to transform classes. Using /full-diff/instrumentator/.*, we can see the diff of all transformations that this instrumentator has done:

Screenshot of http://localhost:7071/full-diff/instrumentator/.*

Yet we also see via /classes that Mockito only transforms the java.util.List interface and all its parents:

Screenshot of http://localhost:7071/classes

The LoggingInstrumentationHandler which is passed to the agent via the cb argument, logs all added and existing transformers.

It is implemented as follows:

public class LoggingInstrumentationHandler implements InstrumentationCallback {
  @Override
  public CallbackAction onAddTransformer(ClassFileTransformer transformer) {
    System.err.println("New transformer " + transformer.getClass().getName());
    return CallbackAction.ALLOW;
  }

  @Override
  public void onExistingTransformer(ClassFileTransformer transformer) {
    System.err.println("Existing transformer " + transformer.getClass().getName());
  }

  @Override
  public CallbackAction onInstrumentation(ClassFileTransformer transformer, ClassArtifact before, ClassArtifact after) {
    return CallbackAction.ALLOW;
  }
}

The meta-agent can also be used via a maven plugin, see the sample project for an example usage. The maven plugin does not yet support the native agent.

How this works

The agent wraps all ClassFileTransformers with a custom transformer that records the diff of the bytecode. It then uses vineflower to decompile the bytecode and diff to compute the diff between the original and the transformed bytecode.

The front-end is implemented using the built-in HttpServer as a simple web server started by the agent.

This is essentially a more capable version of the classviewer-agent.-

Contributions

If you have sample programs where this tool helped to see something interesting, please share. Contributions, issues and PRs are welcome.

Deploy

mvn package -DskipTests=true deploy -U
mvn package -f pom_runtime.xml -DskipTests=true deploy -U

License

MIT, Copyright 2024 SAP SE or an SAP affiliate company, Johannes Bechberger and meta-agent agent contributors

About

Instrument instrumenting agents to see how they transform classes

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •