Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Tests when developing javaagents?

I'm trying to fiddle with Foursquare's HeapAudit, and am attempting to set it up using IntelliJ IDEA. I have managed to get it to build just fine, using the dependencies from the pom.xml.

However, when I actually try to run the JUnit tests, basically all of them fail. I'm guessing this is because using HeapAudit requires the JVM to be started with it as a -javaagent, according to the github:

$ java -javaagent:heapaudit.jar MyTest

Presumably the tests would pass if I put this line in, and referenced the heapaudit.jar i downloaded/built earlier. However, it seems to me that if I make changes the the source, I'm gonna need to re-package this silly .jar file in order to see if it works.

Is there any way of running the tests with a -javaagent without going through the whole rigmarole of compile -> package-into-jar every testing cycle? Perhaps getting IntelliJ to attached the newly-compiled .class files as a -javaagent before running the tests?

like image 890
Li Haoyi Avatar asked Oct 19 '12 18:10

Li Haoyi


1 Answers

1) Have a jar just with a META-INF/MANIFEST.MF

The manifest must be properly configured with Premain-Class and other attributes. The jar doesn't need any other files. Use this jar with the -javaagent. Provided that the agent classes are in the classpath, the agent will start normally.

This might fail when using maven-surefire-plugin with forkMode=never because by default the application classes are loaded in a child ClassLoader.

Works fine with Eclipse and Intellij.

If doing this, double check the manifest syntax (once I spent a long time to figure out that a package name was wrong).

2) Use ea-agent-loader

It will allow you to load the agent (any agent) in runtime (it uses VM.attach()). However the VM.attach() sometimes disrupts debugging and breakpoints might fail to trigger.

It will have the same issues with the surefire in forkMode=never

3) Load the agent in runtime.

Write your on code to load the agent in runtime. And call it from your @BeforeClass You will still need a jar (which you can generate in runtime if you want).

Just you need to call this (only once):

AgentLoader.loadAgentClass(YourAgentClass.class.getName());
like image 186
Daniel Sperry Avatar answered Oct 28 '22 12:10

Daniel Sperry