javaAgent简单使用
2017-08-23 20:58
417 查看
javaAgent
记录之前印象中的使用过程记录,感兴趣的可按照套路来实践下。注意需要使用到tools.jar包
1. 制作hotfix-1.0.jar
Manifest-Version: 1.0
Agent-Class: xxx.xxx.xxxx.JavaDynAgent
Can-Redefine-Classes: true
import java.lang.instrument.Instrumentation; import org.apache.log4j.Logger; public class JavaDynAgent { private static final Logger logger = Logger.getLogger(JavaDynAgent.class); private static Instrumentation instrumentation; private static Object lockObject = new Object(); public static void agentmain(String args, Instrumentation inst) { synchronized(lockObject) { if(instrumentation == null) { logger.info("agentmain called, init instrumentation inst"); instrumentation = inst; }else { logger.info("agentmain called, already init"); } } } public static Instrumentation getInstrumentation() { return instrumentation; } }
2. 项目调用接口类
import java.io.File; import java.io.IOException; import java.lang.instrument.ClassDefinition; import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import com.google.common.base.Preconditions; import com.google.common.io.Files; import com.sun.tools.attach.AgentInitializationException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; public class JavaAgentUtil { private static final Logger logger = Logger.getLogger(JavaAgentUtil.class); private static String basePath; private static String classesPath; private static String jarPath; private static VirtualMachine vm; private static String pid; static { basePath = getBasePath(); //classesPath = basePath + "classes" + "/"; classesPath = basePath + "hotfix" + "/"; jarPath = basePath + "lib" + "/"; // 当前进程pid String name = Managem a753 entFactory.getRuntimeMXBean().getName(); pid = name.split("@")[0]; logger.info("JavaAgentUtil init classesPath = " + classesPath + " jarPath = " + jarPath); } public static String getBasePath() { String clsPath = JavaAgentUtil.class.getResource("").getPath(); String[] strArr = clsPath.split("classes|lib"); return strArr[0]; } public static boolean javaAgent(String root, String[] classArr) throws ClassNotFoundException, IOException, UnmodifiableClassException, AttachNotSupportedException, AgentLoadException, AgentInitializationException { try { // 虚拟机加载 logger.info("init agent attach jvm"); vm = VirtualMachine.attach(pid); vm.loadAgent(jarPath + "hotfix-1.0.jar"); Instrumentation instrumentation = JavaDynAgent.getInstrumentation(); Preconditions.checkNotNull(instrumentation, "initInstrumentation must not be null"); StringBuilder tmpStr = new StringBuilder(); // 1.整理需要重定义的类 List<ClassDefinition> classDefList = new ArrayList<ClassDefinition>(); for (String className : classArr) { Class<?> c = Class.forName(className); String classPath = (StringUtils.isNotBlank(root) ? root : classesPath) + className.replace(".", "/") + ".class"; byte[] bytesFromFile = Files.toByteArray(new File(classPath)); ClassDefinition classDefinition = new ClassDefinition(c, bytesFromFile); classDefList.add(classDefinition); tmpStr.append(className); } // 2.redefine JavaDynAgent.getInstrumentation().redefineClasses(classDefList.toArray(new ClassDefinition[classDefList.size()])); logger.info(" redefine classes success classArr = " + tmpStr.toString()); return true; } catch (Exception e) { logger.error("javaAgent err when redefine class msg = " + e.getMessage()); } finally { if (vm != null) { vm.detach(); logger.info("detach agent jvm"); } } return false; } // reload class files public static boolean loadClass(String[] names){ try { return javaAgent(null, names); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnmodifiableClassException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AttachNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AgentLoadException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AgentInitializationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } }
3. 调用前面接口例子
String[] clsNames = fixnames.split("\\|"); JavaAgentUtil.loadClass(clsNames);
其中fixnames为以|分割的字符串
例如:class1路径|class2路径
相关文章推荐
- 使用异或进行简单的密码加密(JAVA实现)
- Java语言中包的简单使用
- java中使用向量做的一个简单翻页程序
- 图片查看软件使用JAVA编写的,比较简单!从书上看下来的,练习使用!
- 使用java简单模拟ping和telnet的实现
- 使用Java实现对dbf文件的简单读写
- 使用java简单模拟ping和telnet的实现
- java.util.Properties 的一些简单使用
- 使用Java实现对dbf文件的简单读写
- 【Java插件开发】JFreeChart简单使用
- 浅析Java执行外部命令的几个要点(1)——简单的使用范例以及在Cygwin上的注意点
- flex 与 java交互 的一个简单示例 (使用RemoteObject)
- 使用jsp生成验证码使用简单在java或jsp页面调用简单
- JOONE(Java Object-Oriented Network Engine)使用初探(简单实例源代码)
- java连接postgreSQL数据库简单使用
- 使用 java 的反射 和 comparator 实现java bean 的简单排序
- 使用java完成一个简单的播放器的制作
- 关于java -classpath 命令的简单使用
- 使用java简单模拟ping和telnet的实现
- 在ASP中使用简单Java类