package org.gridkit.jvmtool.bstub; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.jar.Attributes; import java.util.jar.Manifest; public class AgentHelper { private static File agentJar; public static synchronized String initAgentJar() throws IOException { if (agentJar != null) { return agentJar.getCanonicalPath(); } File t = File.createTempFile("___", "_"); File tdir = t.getParentFile(); File tt = new File(tdir, "btpack"); tt.mkdir(); byte[] agent = createAgentJar(); String hash = digest(agent, "SHA-256"); File name = new File(tt, "agent-" + hash + ".jar"); if (name.isFile() && name.length() == agent.length) { agentJar = name; return name.getCanonicalPath(); } name.delete(); FileOutputStream fos = new FileOutputStream(name); fos.write(agent); fos.close(); agentJar = name; return name.getCanonicalPath(); } static byte[] createAgentJar() throws IOException { JarBuilderTool builder = new JarBuilderTool(); Manifest mf = builder.getManifest(); mf.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); mf.getMainAttributes().put(new Attributes.Name("Agent-Class"), "net.java.btrace.agent.Main"); mf.getMainAttributes().put(new Attributes.Name("Can-Redefine-Classes"), "true"); mf.getMainAttributes().put(new Attributes.Name("Can-Retransform-Classes"), "true"); builder.addService("net.java.btrace.spi.wireio.CommandImpl"); builder.addService("net.java.btrace.spi.server.ServerImpl"); builder.addPackage("net.java.btrace.agent"); builder.addPackage("net.java.btrace.agent.wireio"); builder.addPackage("net.java.btrace.annotations"); builder.addPackage("net.java.btrace.api.core"); builder.addPackage("net.java.btrace.api.extensions"); builder.addPackage("net.java.btrace.api.extensions.runtime"); builder.addPackage("net.java.btrace.api.extensions.util"); builder.addPackage("net.java.btrace.api.server"); builder.addPackage("net.java.btrace.api.types"); builder.addPackage("net.java.btrace.api.wireio"); builder.addPackage("net.java.btrace.commands"); builder.addPackage("net.java.btrace.ext"); builder.addPackage("net.java.btrace.instr"); builder.addPackage("net.java.btrace.org.objectweb.asm"); builder.addPackage("net.java.btrace.org.objectweb.asm.commons"); builder.addPackage("net.java.btrace.org.objectweb.asm.signature"); builder.addPackage("net.java.btrace.resources"); builder.addPackage("net.java.btrace.runtime"); builder.addPackage("net.java.btrace.server"); builder.addPackage("net.java.btrace.spi"); builder.addPackage("net.java.btrace.spi.server"); builder.addPackage("net.java.btrace.spi.wireio"); builder.addPackage("net.java.btrace.util"); builder.addPackage("net.java.btrace.server.wireio"); builder.addPackage("net.java.btrace.wireio.commands"); builder.addPackage("org.gridkit.nimble.btrace.ext"); byte[] data = builder.collectJar(); return data; } private static String digest(byte[] data, String algorithm) { try { MessageDigest md = MessageDigest.getInstance(algorithm); byte[] digest = md.digest(data); StringBuilder buf = new StringBuilder(); for(byte b: digest) { buf.append(Integer.toHexString(0xF & (b >> 4))); buf.append(Integer.toHexString(0xF & (b))); } return buf.toString(); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } } }