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.
Comments:

hai na, nice blog...rather too much info gotta astore.... good work... bye

Posted by garun42- G.Arunbala on March 19, 2006 at 05:14 AM IST #

good starting point, gonna comibe this with jmx

Posted by luc duponcheel on March 09, 2007 at 02:13 PM IST #

I can execute the command:java -cp $JAVA_HOME/lib/tools.jar:. Attach 1872 helloAgent.jar;and it throws the exception: Exception in thread "main" java.lang.NoClassDefFoundError: AttachTest; the 1872 is the process id of Test; why? can you check it and response to me by email?

Posted by ruanwen on March 20, 2007 at 01:39 PM IST #

Hi ruanwen: I don't know your email id! Few things to check at your end: 1) You need to specify the absolute path of helloAgent.jar in your command line 2) When you created manifest.mf, you need to have newline character after AgentClass: HelloWorldAgent line

Posted by A. Sundararajan on March 20, 2007 at 02:02 PM IST #

Hi A.Sundararajan,Thank you very much! I follow your instructions to modify the manifest.mf and also specify the absolute path of helloAgent.jar, but it also throw the exception: Exception in thread "main" java.lang.NoClassDefFoundError: AttachTest; I run the program on Microsoft Windows XP Home Edition and jdk6.0 platform. I expect your reply! My Email is: ruanwen@ebupt.com

Posted by ruanwen on March 21, 2007 at 06:12 AM IST #

The AttachTest is just the Attach you post above.I am afraid the Class name of Attach conflict with the tools.jar, and then I change the Class name of Attach to AttachTest.

Posted by ruanwen on March 21, 2007 at 06:21 AM IST #

I am not sure what went wrong at your end. You may want to provide little more detail! For example, I don't have a class by the name "AttachTest" in my example. So, you probably modified the code to use your own class names. I'd suggest to try the verbatim stuff as in my entry and then see whether you can reproduce your problem.

Posted by A.Sundararajan on March 21, 2007 at 06:23 AM IST #

Looks like the "comments" crossed! I don't know think there is any issue of name conflict. There is no class by the name "Attach" in tools.jar -- so, it cannot conflict.

Posted by A. Sundararajan on March 21, 2007 at 06:27 AM IST #

I have followed your instructs to modify the command and the exception of java.lang.NoClassDefFoundError disappeared. But another exception is throwed as the following: java.lang.UnsatisfiedLinkError: no attach in java.library.path Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: no providers installed at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:190) at AttachTest.main(AttachTest.java:22) Is it system profile' issue? how to solve this problem?

Posted by ruanwen on March 22, 2007 at 02:09 AM IST #

I use the debug tools with the eclipse;it shows the files of \\d:\\jre\\lib\\sunrsasign.jar \\d:\\jre\\classes not found,and I indeed can't find these files; and then the debug tool shows that sun/tools/attach/WindowsAttachProvider and sun.tools.attach.WindowsAttachProvider and sun/tools/attach/HotSpotAttachProvider and sun.tools.attach.HotSpotAttachProvider and sun/tools/attach/WindowsVirtualMachine and sun.tools.attach.WindowsVirtualMachine and sun/tools/attach/HotSpotVirtualMachine and sun.tools.attach.HotSpotVirtualMachine all ClassNotFoundException, and then it throws the exception:no attach in java.library.path,but I indeed find the class file in the tools.jar. why can't find these classes? Sir,can you check it?

Posted by guest on March 22, 2007 at 02:41 AM IST #

The last comment is post by me.I am sorry to forgot to sign my name.

Posted by ruanwen on March 22, 2007 at 02:45 AM IST #

I use jconsole -debug to monitor the AttachTest runtime ,the log show the following: [Loaded java.net.JarURLConnection from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.JarURLConnection from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.URLJarFile$URLJarFileCloseController from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.JarFileFactory from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.URLJarFile from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.URLJarFile$URLJarFileEntry from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.tools.attach.HotSpotAttachProvider from file:/D:/Java/jdk1.6.0/lib/tools.jar] [Loaded sun.tools.attach.WindowsAttachProvider from file:/D:/Java/jdk1.6.0/lib/tools.jar] [Loaded java.lang.InternalError from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded java.net.UnknownHostException from D:\\Java\\jre1.6.0\\lib\\rt.jar] [Loaded sun.tools.attach.HotSpotVirtualMachine from file:/D:/Java/jdk1.6.0/lib/tools.jar] [Loaded sun.tools.attach.WindowsVirtualMachine from file:/D:/Java/jdk1.6.0/lib/tools.jar] [Loaded java.lang.UnsatisfiedLinkError from D:\\Java\\jre1.6.0\\lib\\rt.jar] I don't understand the path of tools.jar is D:\\Java\\jre1.6.0\\lib\\rt.jar but D:\\Java\\jre1.6.0\\lib\\rt.jar of rt.jar? why are these file seperators different?

Posted by ruanwen on March 22, 2007 at 05:45 AM IST #

I made this test on the Linux platform. The running is ok. So it seems that the java SDK can't support the windows environment.

Posted by ruanwen on March 22, 2007 at 08:56 AM IST #

Hi ruanwen: No, it does work on Windows!. attach-on-demand \*is\* supported on Windows. I'd suggest the following to you:
  • install JDK 6 from http://java.sun.com/javase/6/
  • Do everything in command line -- this is a simple program and so we would be better off removing any IDE dependencies for testing the feature.
  • Make sure that your target application runs on JDK 6 -- only JDK 6 VM supports attach-on-demand.
  • Find the correct target process id by "jps".

Posted by A. Sundararajan on March 23, 2007 at 02:18 AM IST #

I am so sorry. I have followed your instructions and test the feature step by step many times.All failed on the Windows platform,but successed on the Linux Platform.I am really puzzled. I beg your further test on windows and give me help.My operation System is Window XP Home Edition,version.2002.

Posted by guest on March 23, 2007 at 10:02 AM IST #

The above is post by me whose ip address is 218.249.60.66

Posted by ruanwen on March 23, 2007 at 10:04 AM IST #

Hi, I don't think I can help further here. As for the feature, it is supported on Windows. I'd want you to double check with command line (with classpath separator etc.) and then if you still think it is a bug, please file a bug.

Posted by A. Sundararajan on March 23, 2007 at 11:44 AM IST #

Looks like the JRE is in D:\\Java\\jre1.6.0 and the SDK in D:\\Java\\jdk1.6.0. The Attach API is not included in the JRE installation so launch the SDK's java.exe and it should work.

Posted by Alan on March 23, 2007 at 12:18 PM IST #

Hi,you are so wise.You point the key to the solution.I launch the java.exe in the D:\\java\\jdk1.6.0\\bin directory and the result is ok.Thank you,Alan.I am puzzled by the java.exe.Because during the installing of jdk,window will install the java.exe javac.exe and so on in the \\windows\\system32 directory. The SDK also contains the JRE in the D:\\java\\jdk1.6.0\\jre,meanwhile windows also install the jre in the D:\\Java\\jre1.6.0. I don't know why the java.exe in the system32 directory can't call the attach api in the D:\\java\\jdk1.6.0\\lib? Would you like to explain it to me? Any way , thanks to Alan and A.Sundararajan!

Posted by ruanwen on March 23, 2007 at 12:48 PM IST #

Hi, I saw this agent thing of yours.But I have a question.When I tried to connect using this agent to a JONAS server pid it is giving me C:\\work_temp>java Attach 5488 helloWorldAgent.jar Exception in thread "main" com.sun.tools.attach.AgentLoadException: Agent JAR no t found or no Agent-Class attribute at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachin e.java:99) at Attach.main(Attach.java:19) Do u mean that it will only connect to the processes which are doing a System.out.println("Hello World"); ????? Sounds strange? Try to help me on this please?

Posted by Bohemian on April 26, 2007 at 04:01 PM IST #

C:\\work_temp>java Attach 5488 helloWorldAgent.jar Exception in thread "main" com.sun.tools.attach.AgentLoadException: Agent JAR no t found or no Agent-Class attribute at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachin e.java:99) at Attach.main(Attach.java:19) This agent is not able to attach to any of the other PIDs on my system except the Test !

Posted by Bohemian on April 26, 2007 at 04:02 PM IST #

Hi Bohemian: You need to provide the full (absolute) path of the agent jar file in the command line. Relative paths are not accepted.

Posted by A. Sundararajan on April 29, 2007 at 01:41 AM IST #

Post a Comment:
Comments are closed for this entry.
About

sundararajan

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Links

No bookmarks in folder

Blogroll

No bookmarks in folder

News

No bookmarks in folder