构建自己的监测器【2】-javaagent参数使用

 javaAgent

 javaAgent是从JDK1.5及以后引入的,在1.5之前无法使用,也可以叫做java代理。

1. 代理 (agent) 是在你的main方法前的一个拦截器 (interceptor),也就是在main方法执行之前,执行agent的代码。

agent的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载,被同一的安全策略 (security policy) 和上下文 (context) 所管理。

那么怎样写一个java agent? 在java5和java6中只需要实现premain这个方法:
public static void premain(String agentArgs, Instrumentation inst) 

例如:

package seeeyou.monitor;

import java.lang.instrument.Instrumentation;

public class MyAgent {
	public static void premain(String agentOps, Instrumentation inst){
		System.out.println(agentOps);
	}
}

如果找不到上面的这种premain的定义,还会尝试调用下面的这种premain定义:
public static void premain(String agentArgs)

2.写完这个代理类后,需要打成jar包,在jar包里面的 META-INF/MAINIFEST.MF 必须包含 Premain-Class这个属性。
如下:
Manifest-Version: 1.0
Premain-Class: seeeyou.monitor.MyAgent
Can-Redefine-Classes: true
需要注意的是,第四行是空行的,这一行必须有,否则绝对会报错。
目录结构基本如下图:


3.在一个java应用中,-javaagent这个参数的个数是不限的,你可以指定多个javaagent,所有的javaagent会按顺序执行,执行完各个agent之后,再执行main方法。比如
set JAVA_OPTS=%JAVA_OPTS% -javaagent:D:/tools/myagent1.jar  -javaagent:D:/tools/myagent2.jar  -javaagent:D:/tools/myagent3.jar 
那么执行顺序就是:myagent1.premain  -> myagent2.premain -> myagent.premain  ->myprogram.main

4.放在main方法之后的premain方法是不会被执行的。比如这个运行:
jar -javaagent:D:/tools/myagent1.jar -jar myprogram.jar  -javaagent:D:/tools/myagent2.jar  -javaagent:D:/tools/myagent3.jar 
这个执行顺序就是:myagent1.premain  -> myprogram.main -> myagent2.premain  ->myagent3.premain
5. 每一个java agent 都可以接收一个字符串类型的参数,也就是premain中的 agentArgs ,这个agentArgs是通过java option中定义的。
如: java - javaagent :myagent.jar=thisIsAgentArgs -jar MyProgram.jar

myagent中premain接收到的agentArgs的值将是”thisIsAgentArgs” (不包括双引号)

6. 参数中的Instrumentation:通过参数中的Instrumentation inst,添加自己定义的ClassFileTransformer,来改变class文件。关于instrument,后面再介绍
7.通过java agent就可以不用修改原有的java程序代码,通过agent的形式来修改或者增强程序了,或者做热启动等等。
 

你可能感兴趣的:(系统维护,编程开发)