Java.lang.Instrument Proxy Agent Use

Source: Internet
Author: User
Tags jboss

java.lang.Instrument包is introduced in JDK5, the programmer modifies the class code dynamically by modifying the bytecode of the method. This is usually done before the main method invocation of the class, which specifies the proxy class for that class, by Java.

(1) The agent is an interceptor (interceptor) before your main method, which is the code that executes the agent before the main method executes.
The code of the agent runs in and is loaded with your main method, and 同一个JVM 同一个system classloader is managed by the same 安全策略 (security policy) 上下文 (context) .
Agent The name is a bit misleading, and it's not quite the same as the agent we generally understand. Java agents are relatively simple to use. How do I write a Java agent? Just implement Premain this method:
public static void premain(String agentArgs, Instrumentation inst)
If this premain definition is not found in JDK 6, it will also attempt to invoke the following Premain definition:
public static void premain(String agentArgs)

(2) The Agent class must be hit into a jar package, and then inside META-INF/MAINIFEST.MF , must contain Premain-Class this attribute.
Here is an example of a MANIFEST.MF:

manifest-version:1.0
Premain-class:myagent1
Created-by:1.6.0_06

Then putMANIFEST.MFAdd to your jar package. The following is a list of manifest attributes for the agent jar file:
Premain-class
IfJVM 启动时指定了代理, this property specifies the proxy class, which is the class that contains the Premain method. This property is required if a proxy is specified at the start of the JVM. If the property does not exist, then the JVM aborts. Note: This property is the class name, not the file name or path.
Agent-class
If the implementation supports VM startup某一时刻启动代理的机制, then this property specifies the proxy class. That is, the class that contains the Agentmain method. This property is required and if it does not exist, the agent will not start.注:这是类名,而不是文件名或路径
Boot-class-path
Sets the path list for the boot ClassLoader search. A path represents a directory or library (usually referenced as a JAR or zip library on many platforms).查找类的特定于平台的机制失败后,引导类加载器会搜索这些路径。 Search for paths in the order listed. The path in the list is separated by one or more spaces. Path component syntax for paths using hierarchical URIs. If the path starts with a slash character ("/"), it is an absolute path, otherwise a relative path. Relative paths are resolved based on the absolute path of the proxy JAR file. The malformed path and the nonexistent path are ignored. If the agent is started at some point after the VM starts, the path that does not represent the JAR file is ignored. This property is optional.
can-redefine-classes
Boolean value (True or FALSE, regardless of capitalization). Whether the classes required by this proxy can be redefined. Values other than true are treated as false. This property is optional and the default value is False.
can-retransform-classes
Boolean value (True or FALSE, regardless of capitalization). Whether the classes required by this proxy can be re-converted. Values other than true are treated as false. This property is optional and the default value is False.
Can-set-native-method-prefix
Boolean value (True or FALSE, regardless of capitalization). Whether you can set the native method prefix that is required by this proxy. Values other than true are treated as false. This property is optional and the default value is False.

(3) All of these agent's jar packages are automatically added to the classpath of the program. So there is no need to manually add them to the classpath. Unless you want to specify the order of Classpath.

(4) There is no limit to the number of-javaagent parameters in a Java program, so you can add as many Java agents as you have. All Java agents are executed in the order you define them.
For example:

Java-javaagent:myagent1.jar-javaagent:myagent2.jar-jar Myprogram.jar

Assume that the main function inside the Myprogram.jar is in MyProgram. Myagent1.jar, Myagent2.jar, the Premain classes implemented in these 2 jar packages are MyAgent1, MyAgent2
The order in which the programs are executed will be:

Myagent1.premain, Myagent2.premain, Myprogram.main

(5) In addition, the premain that are placed after the main function will not be executed, for example:

Java-javaagent:myagent1.jar-jar Myprogram.jar-javaagent:myagent2.jar

MyAgent2 are placed behind Myprogram.jar, so MyAgent2 's premain will not be executed, so the result of execution will be:

Myagent1.premain-Myprogram.main

(6) Each Java agent can receive a parameter of a string type, which is the Agentargs in Premain, which is defined in Java option. For example:

Java-javaagent:myagent2.jar=thisisagentargs-jar Myprogram.jar

The value of Agentargs received in MyAgent2 Premain will be "Thisisagentargs" (not including double quotes).

Instrumentation in the

(7) Parameter: Change the class file by adding your own defined Classfiletransformer through the instrumentation inst in the parameter. The custom transformer here implements the Transform method, which provides a modification to the bytecode of the actual class to be executed, even to the point where another class method is executed. For example:
Write Agent class :

Import Java.lang.instrument.instrumentation;import Java.lang.instrument.instrumentation;import Java.lang.instrument.classfiletransformer;public class Perfmonagent {    private static instrumentation Inst = null;< c1/>/**     * This method is called before the application ' s main-method are called,     * When this agent was specified to The Java VM.     **/public    static void Premain (String Agentargs, instrumentation _inst) {        System.out.println (" Perfmonagent.premain () was called. ");        Initialize The static variables we use for track information.        Inst = _inst;        Set up the class-file transformer.        Classfiletransformer trans = new Perfmonxformer ();        System.out.println ("Adding a Perfmonxformer instance to the JVM.");        Inst.addtransformer (trans);    }}

写ClassFileTransformer类

Import Java.lang.instrument.classfiletransformer;import Java.lang.instrument.classfiletransformer;import Java.lang.instrument.illegalclassformatexception;import Java.security.protectiondomain;import javassist. Cannotcompileexception;import javassist. Classpool;import javassist. Ctbehavior;import javassist. Ctclass;import javassist. Notfoundexception;import Javassist.expr.expreditor;import Javassist.expr.methodcall;public class PerfMonXformer Implements Classfiletransformer {public byte[] transform (ClassLoader loader, String className, class<?> Classbei  ngredefined, Protectiondomain Protectiondomain, byte[] classfilebuffer) throws illegalclassformatexception {byte[]        transformed = NULL;        System.out.println ("Transforming" + className);        Classpool pool = Classpool.getdefault ();        Ctclass cl = null;            try {cl = Pool.makeclass (New Java.io.ByteArrayInputStream (Classfilebuffer));     if (cl.isinterface () = = False) {           Ctbehavior[] methods = Cl.getdeclaredbehaviors ();                        for (int i = 0; i < methods.length; i++) {if (methods[i].isempty () = = False) {                    Domethod (Methods[i]);            }} transformed = Cl.tobytecode (); }} catch (Exception e) {System.err.println ("Could not instrument" + className + "        , exception: "+ E.getmessage ());            } finally {if (CL! = null) {Cl.detach ();    }} return transformed; } private void Domethod (Ctbehavior method) throws Notfoundexception, cannotcompileexception {//Meth        Od.insertbefore ("Long stime = System.nanotime ();");        Method.insertafter ("System.out.println (\" Leave "+method.getname () +" and time:\ "+ (System.nanotime ()-stime));"); Method.instrument (New Expreditor () {public void edit (Methodcall m) throws Cannotcompileexception {m.replace ("{Long stime = System.nanotime (); $_ = $proceed ($$); System.out.println (\ "" + m.getclassname () + "."            +m.getmethodname () + ": \" + (System.nanotime ()-stime));} ");    }        }); }}

The above two classes are the core of the agent, the JVM starts and calls Perfmonagent.premain before the app loads, and then instantiates a custom classfiletransforme in Perfmonagent.premain Perfmonxformer, and by Inst.addtransformer (trans), adding Perfmonxformer instances to the instrumentation instance (passed in by the JVM), which makes 应用中的类加载的时候 Perfmonxformer.transform will be called, you can change the loaded class in this method, really a bit magical, in order to change the class bytecode, I use JBoss javassist, although you do not have to use it, But JBoss Javassist is really powerful and makes it easy for you to change the byte code of a class.

In the above method I add a long stime = System.nanotime () in the method entry of each class by changing the byte code of the class, and the exit of the method is added to the System.out.println (" Methodclassname.methodname: "+ (System.nanotime ()-stime));

Java.lang.Instrument Proxy Agent Use

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.