There are two ways to get an instance of the instrumentation interface:
-
Specifies the agent class when the JVM is started. In this way, an instance of instrumentation is passed through the Premain method of the agent class.
-
The JVM provides a mechanism to turn on the agent when the JVM is started. In this case, the Instrumention instance is passed in through the Agentmain in the agent code.
The Java agent is explained in the JDK Package specification: An agent is deployed as a jar file. In the jar file, specify which class to use as the agent class in manifest. The specific implementation includes
The agent is opened directly via the command line and the JVM launcher is supported, and the tool is attach to the program.
The following example illustrates the use of Javaagent + instrumentation.
by Preagent the way before the program starts : (This example implements the output of all JVM load class names and adds log before and after the SayHello method call of the People Class)
1 People class
public class People {public void SayHello () {System.out.println ("Hello!!!!"); }}
2 Implement a Classfiletransformer class:
This implementation is implemented by the agent to load the transformation into class files in the JVM. This kind of conversion occurs before the class file is loaded into the JVM. So this can achieve the effect of class AOP programming.
public class peopleclassfiletransformer implements classfiletransformer { /** * Modify bytecode by Javassist * @ param loader * @param classname * @param classBeingRedefined * @param protectionDomain * @param classfileBuffer * @return * @throws IllegalClassFormatException */ @Override public byte[] transform (Classloader loader, String className, Class<?> classBeingRedefined, ProtectionDomain Protectiondomain, byte[] classfilebuffer) throws IllegalClassFormatException { &nbSp; system.out.println ("Load class:" +classname); if (" Com.yao.intrumentation.People ". Equals (ClassName)) { try { //modifying SayHello method byte code by javassist ctclass ctclass= classpool.getdefault (). Get (ClassName.replace ('/', '. ')); CtMethod Sayhellomethod=ctclass.getdeclaredmethod ("SayHello"); sayhellomethod.insertbefore ("System.out.println (\" before SayHello----\ ");"); Sayhellomethod.inserTafter ("System.out.println (\" After sayhello----\ "); return Ctclass.tobytecode (); } catch (notfoundexception e) { e.printstacktrace (); } catch (cannotcompileexception e) { e.printstacktrace (); } catch (ioexception e) { e.printstacktrace (); } } return classfilebuffer; }}
3 Write the agent, which must contain the Premain method. and add the MANIFEST.MF to the Meta-inf and add it to the list.
Premain-class:com.yao.intrumentation.myagent
public class Myagent {/** * This method is a class required for the agent class * @param Agentargs * @param inst */public static VO ID premain (String agentargs,instrumentation Inst) {//Join Classfiletransfomer Inst.addtransformer (new PEOPLECLA Ssfiletransformer ()); }}
4 Packing Agent Class (Here you can take the above Classfiletransfer myagent alone to pack it.) Here we put all the code together for the sake of the aspect. )
After the code is compiled and packaged under target/classes/and the M parameter is specified manifest
JAR-CVFM Myagent.jar meta-inf/manifest. MF *//execute in your own project directory such as MAVEN directory structure//under compiled target/class/
5 Testing the main class:
public class Testmain {public static void main (String[]args) {people people=new people (); People.sayhello (); }}
Start here in order to facilitate the resolution of the referenced Javassist jar package classpath problem, I directly in the IntelliJ specify the VM parameters to start the main method above, so do not have to manually set CLASSPATH on the command line.
-javaagent:/users/yao/workspace/private/javaspi/target/classes/myagent.jar refers to the agent jar location that I packaged.
The result is entered as follows:
load class:java/lang/invoke/methodhandleimplload class:java/lang/invoke/methodhandleimpl$1load class:java/lang/invoke/methodhandleimpl$2load class:java/util/function/functionload class:java/lang/ invoke/methodhandleimpl$3load class:java/lang/invoke/methodhandleimpl$4load class:java/lang/ classvalueload class:java/lang/classvalue$entryload class:java/lang/classvalue$identityload Class:java/lang/classvalue$versionload class:java/lang/invoke/membername$factoryload class:java/lang /invoke/methodhandlestaticsload class:java/lang/invoke/methodhandlestatics$1load class:sun/misc/ Postvminithookload class:sun/launcher/launcherhelperload class:com/yao/intrumentation/testmainload class:sun/launcher/launcherhelper$fxhelperload class:java/lang/class$methodarrayload class: Java/lang/voidload class:com/yao/intrumentation/peoplebefore sayhello----hello !!!! After sayhello----LOAD&NBSP;CLASS:JAVA/lang/shutdownload class:java/lang/shutdown$lock
The following is a brief introduction to the Agentmain way through attach to a running JVM program :
1 writing the Agent class
public class Mainagent {public static void Agentmain (String args, Instrumentation inst) {class[] classes = Inst . getallloadedclasses (); for (Class cls:classes) {System.out.println (Cls.getname ()); } }}
2 Write a long time running main
public class Runningapp {public static void main (String[]args) throws Interruptedexception {people people=new People (); Thread.Sleep (1000*1000); }}
3 Modifying MANIFEST.MF
Agent-class:com.yao.intrumentation.mainagent
Packaged into jars in a way similar to the above
4 Writing Attach Programs
public class Testmainagent {public static void main (String[]args) throws Interruptedexception, IOException, Agentloade Xception, Agentinitializationexception, attachnotsupportedexception {virtualmachine vm = VirtualMachine.attach (arg S[0]); Running Java program PS ID vm.loadagent ("/users/yao/workspace/private/javaspi/target/classes/agentmain.jar"); The agent jar location just compiled}}
Run the Runningapp boot JPS get the PS ID, pass to the above program, run to see the JVM loaded all class files
Reprint Annotated: http://my.oschina.net/robinyao/blog/489767
Specific code: https://github.com/WangErXiao/JavaSPI/tree/master/src/main/java/com/yao/intrumentation
Instrumentation feature description (javaagent)