« December 2005 »
SunMonTueWedThuFriSat
    
1
3
4
5
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
       
Today
XML

Blog::Navigation

GetJava Download Button
Get the Source
Personal Blog

Blog::Referers

Today's Page Hits: 649

Powered by Roller Weblogger.
« Previous day (Dec 1, 2005) | Main | Next day (Dec 3, 2005) »
20051202 Friday December 02, 2005

Using Mustang's Attach API

You may have read that Mustang JDK now includes attach-on-demand. i.e., With the Mustang JDK you can now attach jconsole to any application, even if it wasn't launched with the magic -Dcom.sun.management.jmxremote. In fact, this is not specific to jconsole agent. You can load any suitably coded native or Java agent into running JVM using the attach API. Let us see how to write a simple "hello world"agent. A typical JVM agent would bytecode instrument classes on class load and/or when classes are being redefined. But, we are interested in just learning attach API. So, here is a simple agent that -- well, prints "Hello agent!"


import java.lang.instrument.*;

public class HelloWorldAgent {
    /* NOTE: agentmain is the special method that 
       will be called when this agent is loaded */
    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("Hello agent!");
        if (agentArgs != null) {
            System.out.println("my args are: " + agentArgs);
        }
    }
}

Compile the above program and create a jar manifest file like manifest.mf shown below:


Agent-Class: HelloWorldAgent

In the above manifest file, we identify HelloWorldAgent class to be the agent class. Now, we can jar the code with the command:


    jar cvfm helloAgent.jar manifest.mf HelloWorldAgent.class


Now, we have written a JVM agent that can loaded. How do we load it on a running JVM? We use com.sun.tools.attach (a.k.a attach API) API.


import com.sun.tools.attach.*;

public class Attach {
    public static void main(String[] args) throws Exception {

        if (args.length != 2) {
            System.out.println("usage: java Attach  ");
            System.exit(1);
        }

        // This program accepts two parameters:
        //    1. The pid of the JVM on which we want to load an agent
        //    2. The full path of the agent jar file to be loaded

        // JVM is identified by process id (pid).
        VirtualMachine vm = VirtualMachine.attach(args[0]);

        // load a specified agent onto the JVM
        vm.loadAgent(args[1], null);
    }
}


When compiling above code, you need to put tools.jar in classpath. I assume $JAVA_HOME is where your JDK is installed.


    javac -cp $JAVA_HOME/lib/tools.jar Attach.java


Now, we have
  1. agent as a jar file (helloAgent.jar)
  2. client that initiates agent load (Attach)
Let us write a simple Java Test program with an infinite-loop:


public class Test {
        public static void main(String[] args) throws Exception {
             System.out.println("Main...");
             while(true);
        }
}

After compiling and running the above Test program, we can note down the pid of it using jps utility. Now, we can attach and load helloAgent.jar using the command:


    java -cp $JAVA_HOME/lib/tools.jar:. Attach <pid-of-Test-program> <path-of-the-helloAgent-jar>


If everything goes well, you should see "Hello agent!" being printed from your Test program.



( Dec 02 2005, 09:06:09 AM IST ) Permalink Comments [22] del.icio.us | furl | simpy | slashdot | technorati | digg

Copyright (C) 2005, A. Sundararajan's Weblog