package com.github.ompc.greys.agent; import java.lang.instrument.Instrumentation; import java.util.jar.JarFile; /** * 代理启动类 * Created by oldmanpushcart@gmail.com on 15/5/19. */ public class AgentLauncher { // 全局持有classloader用于隔离greys实现 private static volatile ClassLoader greysClassLoader; public static void premain(String args, Instrumentation inst) { main(args, inst); } public static void agentmain(String args, Instrumentation inst) { main(args, inst); } /** * 重置greys的classloader<br/> * 让下次再次启动时有机会重新加载 */ public synchronized static void resetGreysClassLoader() { greysClassLoader = null; } private static ClassLoader loadOrDefineClassLoader(String agentJar) throws Throwable { final ClassLoader classLoader; // 如果已经被启动则返回之前启动的classloader if (null != greysClassLoader) { classLoader = greysClassLoader; } // 如果未启动则重新加载 else { classLoader = new AgentClassLoader(agentJar); // 获取各种Hook final Class<?> adviceWeaverClass = classLoader.loadClass("com.github.ompc.greys.core.advisor.AdviceWeaver"); // 初始化全局间谍 Spy.initForAgentLauncher( classLoader, adviceWeaverClass.getMethod("methodOnBegin", int.class, ClassLoader.class, String.class, String.class, String.class, Object.class, Object[].class), adviceWeaverClass.getMethod("methodOnReturnEnd", Object.class, int.class), adviceWeaverClass.getMethod("methodOnThrowingEnd", Throwable.class, int.class), adviceWeaverClass.getMethod("methodOnInvokeBeforeTracing", int.class, Integer.class, String.class, String.class, String.class), adviceWeaverClass.getMethod("methodOnInvokeAfterTracing", int.class, Integer.class, String.class, String.class, String.class), adviceWeaverClass.getMethod("methodOnInvokeThrowTracing", int.class, Integer.class, String.class, String.class, String.class, String.class), AgentLauncher.class.getMethod("resetGreysClassLoader") ); } return greysClassLoader = classLoader; } private static synchronized void main(final String args, final Instrumentation inst) { try { // 传递的args参数分两个部分:agentJar路径和agentArgs // 分别是Agent的JAR包路径和期望传递到服务端的参数 final int index = args.indexOf(';'); final String agentJar = args.substring(0, index); final String agentArgs = args.substring(index, args.length()); // 将Spy添加到BootstrapClassLoader inst.appendToBootstrapClassLoaderSearch( new JarFile(AgentLauncher.class.getProtectionDomain().getCodeSource().getLocation().getFile()) ); // 构造自定义的类加载器,尽量减少Greys对现有工程的侵蚀 final ClassLoader agentLoader = loadOrDefineClassLoader(agentJar); // Configure类定义 final Class<?> classOfConfigure = agentLoader.loadClass("com.github.ompc.greys.core.Configure"); // GaServer类定义 final Class<?> classOfGaServer = agentLoader.loadClass("com.github.ompc.greys.core.server.GaServer"); // 反序列化成Configure类实例 final Object objectOfConfigure = classOfConfigure.getMethod("toConfigure", String.class) .invoke(null, agentArgs); // JavaPid final int javaPid = (Integer) classOfConfigure.getMethod("getJavaPid").invoke(objectOfConfigure); // 获取GaServer单例 final Object objectOfGaServer = classOfGaServer .getMethod("getInstance", int.class, Instrumentation.class) .invoke(null, javaPid, inst); // gaServer.isBind() final boolean isBind = (Boolean) classOfGaServer.getMethod("isBind").invoke(objectOfGaServer); if (!isBind) { try { classOfGaServer.getMethod("bind", classOfConfigure).invoke(objectOfGaServer, objectOfConfigure); } catch (Throwable t) { classOfGaServer.getMethod("destroy").invoke(objectOfGaServer); throw t; } } } catch (Throwable t) { t.printStackTrace(); } } }