通过VirtualMachine动态加载agent.jar,不使用-javaagent的方式,不过这种方式需要jdk的tools包。
public static void premain(String agentArgs, Instrumentation inst){ inst.addTransformer(new MyClasTransform()); } public static class MyClasTransform implements ClassFileTransformer{ @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { return classfileBuffer; } } public static void main(String[] args) throws Exception { VirtualMachine vm = VirtualMachine.attach(getPid()); vm.loadAgent(getAgentJar()); } public static String getAgentJar() throws IOException { URL resource = Agent.class.getClassLoader().getResource(Agent.class.getName().replace(".","/")+".class"); URLConnection urlConnection = resource.openConnection(); if(urlConnection instanceof JarURLConnection){ JarURLConnection jarURLConnection = (JarURLConnection) urlConnection; return jarURLConnection.getJarFile().getName(); } else { InputStream in = urlConnection.getInputStream(); ZipOutputStream out = null; File file = null; try{ file = File.createTempFile(Agent.class.getName(),".jar"); }catch (Exception e){ } file.deleteOnExit(); try{ out = new ZipOutputStream(new FileOutputStream(file)); out.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF")); PrintWriter writer = new PrintWriter(new OutputStreamWriter(out)); writer.println("Agent-Class: "+Agent.class.getName()); writer.println("Can-Redefine-Classes: true"); writer.println("Can-Retransform-Classes: true"); writer.flush(); }finally { out.closeEntry(); } out.putNextEntry(new ZipEntry(Agent.class.getName().replace(".","/")+".class")); try { byte[] bite= new byte[1024]; while (in.read(bite) != -1){ out.write(bite); } }finally { out.closeEntry(); } return file.getAbsolutePath(); } } public static String getPid(){ RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); String pid = runtimeMXBean.getName(); if(pid.contains("@")){ pid = pid.substring(0,pid.indexOf("@")); } return pid; }