X

Sundararajan's Weblog

  • Java
    December 1, 2005

Using Mustang's Attach API

Guest Author

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.

Join the discussion

Comments ( 22 )
  • garun42- G.Arunbala Saturday, March 18, 2006
    hai na,
    nice blog...rather too much info gotta astore....
    good work...
    bye
  • luc duponcheel Friday, March 9, 2007
    good starting point,
    gonna comibe this with jmx
  • ruanwen Tuesday, March 20, 2007
    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?
  • A. Sundararajan Tuesday, March 20, 2007
    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
  • ruanwen Wednesday, March 21, 2007
    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
  • ruanwen Wednesday, March 21, 2007
    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.
  • A.Sundararajan Wednesday, March 21, 2007
    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.
  • A. Sundararajan Wednesday, March 21, 2007
    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.
  • ruanwen Wednesday, March 21, 2007
    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?
  • guest Wednesday, March 21, 2007
    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?
  • ruanwen Wednesday, March 21, 2007
    The last comment is post by me.I am sorry to forgot to sign my name.
  • ruanwen Thursday, March 22, 2007
    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?
  • ruanwen Thursday, March 22, 2007
    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.
  • A. Sundararajan Thursday, March 22, 2007
    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".

  • guest Friday, March 23, 2007
    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.
  • ruanwen Friday, March 23, 2007
    The above is post by me whose ip address is 218.249.60.66
  • A. Sundararajan Friday, March 23, 2007
    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.
  • Alan Friday, March 23, 2007
    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.
  • ruanwen Friday, March 23, 2007
    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!
  • Bohemian Thursday, April 26, 2007
    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?
  • Bohemian Thursday, April 26, 2007
    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 !
  • A. Sundararajan Saturday, April 28, 2007
    Hi Bohemian: You need to provide the full (absolute) path of the agent jar file in the command line. Relative paths are not accepted.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.