7/24/2006

The -javaagent: Option

The -javaagent: is introduced in JDK 5, and it may be late to talk about any new features in JDK 5, while JDK 6 is just around the corner. I started to use it recently but at first couldn't find any good documentation on this option.

java -help shows a brief message:

-javaagent:<jarpath>[=<options>]
load Java programming language agent, see java.lang.instrument
JDK tools doc page doesn't give much more info. The official one is at the Javadoc page for java.lang.instrument, as suggested by java -help

Here is my quick summary with comments:

1. An agent is just an interceptor in front of your main method, executed in the same JVM and loaded by the same system classloader, and governed by the same security policy and context.

The name is misleading, since the word agent usually suggests something working remotely and separately from the primary entity. But it turns out the java agent as used in -javaagent: is much simpler than that.

How to write a java agent? Just implement this method:
public static void premain(String agentArgs, Instrumentation inst);
2. Agent classes must be packaged in jar file format whose META-INF/MANIFEST.MF contains at least one additional attribute: Premain-Class. An example of MANIFEST.MF:
Manifest-Version: 1.0
Premain-Class: javahowto.JavaAgent
Created-By: 1.6.0_06 (Sun Microsystems Inc.)
Once you have the custom MANIFEST.MF file, run jar command with cvfm option to create the agent jar:
/projects/Hello/build/classes $
jar cvfm ../../myagent.jar ../../mymanifest.mf javahowto/MyAgent.class
3. All these agent jars are automatically appended to the classpath. So no need to add them to classpath, unless you want to reorder classpath elements.

4. One java application may have any number of agents by using -javaagent: option any number of times. Agents are invoked in the same order as specified in options.

5. Each agent may also take String-valued args. I guess that's the reason why we have to use this option multiple times for multiple agents. Otherwise, we could've just done something like: -javaagent agent1.jar:agent2.jar, which is incorrect.

6. It's convenient for java application integration. Now I can enhance/modify the behavior of an application without changing its source code.

7. JavaEE 5 has many similar construts, such as interceptors in EJB 3, and EntityListener in Java Persistence API. In JavaEE, they are managed by some sort of containers, so their semantics is much richer than javaagent.

9 comments:

Sofien said...

Does the agent have to have a main method plus the premain method or it only has to have premain?

admin said...

Only the premain method is needed:

public static void premain(
String agentArgs,
Instrumentation instr)
throws Exception {

}

Your main method should be in another class that is to be run with java command.

You could have a main method in the agent class but it will be ignored when this class is used as an agent.

Danail Nachev said...

Your summary is very misleading. The power of instrumentation agents is in the ability to instrument classes upon loading. The premain() method serves merely as a entry point for the agent.

Have a closer view of java.lang.instrument package.

Benedikt Arnold said...

@Danail:

I don't think the article is misleading. This article simply doesn't cover instrumentation. Agents could be used for instrumentation but thats not the only use case and this post is an great intruduction into java agents.

Danail Nachev said...

The article states:
...
An agent is just an interceptor in front of your main method...

This is too shallow description of what an agent can do. There is a link to the full description of an agent capabilities, but the summary here doesn't even mentions how they operate - they are represented with some class/library which can be invoked before the normal main class is invoked. This is not even close to the real power of an agent.

The article mentions that the applications behaviour can be changed without touching the code, but the big mistery remains - how? Shouldn't be this included in the summary of what is javaagent, considering this is the only thing javaagent was designed for.

In the end I want to note that the name isn't misleading. java agent operates on very different level of your applications and can work without any knowledge about the application being run in the VM. Using javaagents, a simple profiler can be implemented.

Raja Nagendra Kumar said...

The Concept of Agent is extensively used in AOP for load time wavering.

frankluo said...

does any one have luck with an agent and multiple jars? For example, one jar with my agent class, then log4j.jar.

Ted said...

As Javin stated, I would also be interested in learning the uses of javaagent.

Anonymous said...

Hi to all!

I know that this is an old topic, but I´m facing the following error when starting the JavaAgent, could you please advice if it is a known error and how to solve it.

The execution of ./JavaAgent.jar failed. The reason is probably that ./JavaAgent.jar doesn't contain the MainClass in MANIFEST.MF.
If you want to unpack ./JavaAgent.jar, call:
jar -xf ./JavaAgent.jar