Skip to content

Instantly share code, notes, and snippets.

@heipacker
Created April 2, 2016 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heipacker/de35ba118e472bc93cb0d6be53981c2e to your computer and use it in GitHub Desktop.
Save heipacker/de35ba118e472bc93cb0d6be53981c2e to your computer and use it in GitHub Desktop.
manualAttach
private String jarFilePath = "/home/fupan/IdeaProjects/agentTest/agent-jar/target/agent-jar-1.0-SNAPSHOT.jar";
private static void attachAgent() {
TestAgent testAgent = new TestAgent();
testAgent.loadAgent();
}
void loadAgent() {
VirtualMachine vm;
if (AttachProvider.providers().isEmpty()) {
String vmName = System.getProperty("java.vm.name");
if (vmName.contains("HotSpot")) {
vm = getVirtualMachineImplementationFromEmbeddedOnes();
} else {
String helpMessage = getHelpMessageForNonHotSpotVM(vmName);
throw new IllegalStateException(helpMessage);
}
} else {
vm = attachToRunningVM();
}
loadAgentAndDetachFromRunningVM(vm);
}
private static AttachProvider ATTACH_PROVIDER = new AttachProvider() {
@Override
public String name() {
return null;
}
@Override
public String type() {
return null;
}
@Override
public VirtualMachine attachVirtualMachine(String s) throws AttachNotSupportedException, IOException {
return null;
}
@Override
public List<VirtualMachineDescriptor> listVirtualMachines() {
return null;
}
};
private static VirtualMachine getVirtualMachineImplementationFromEmbeddedOnes() {
Class<? extends VirtualMachine> vmClass = findVirtualMachineClassAccordingToOS();
Class<?>[] parameterTypes = {AttachProvider.class, String.class};
String pid = getProcessIdForRunningVM();
try {
// This is only done with Reflection to avoid the JVM pre-loading all the XyzVirtualMachine classes.
Constructor<? extends VirtualMachine> vmConstructor = vmClass.getConstructor(parameterTypes);
VirtualMachine newVM = vmConstructor.newInstance(ATTACH_PROVIDER, pid);
return newVM;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoClassDefFoundError e) {
throw new IllegalStateException("Native library for Attach API not available in this JRE", e);
} catch (UnsatisfiedLinkError e) {
throw new IllegalStateException("Native library for Attach API not available in this JRE", e);
}
}
private static Class<? extends VirtualMachine> findVirtualMachineClassAccordingToOS() {
if (File.separatorChar == '\\') {
// return WindowsVirtualMachine.class;
}
String osName = System.getProperty("os.name");
if (osName.startsWith("Linux") || osName.startsWith("LINUX")) {
return LinuxVirtualMachine.class;
} else if (osName.startsWith("Mac OS X")) {
// return BsdVirtualMachine.class;
} else if (osName.startsWith("Solaris")) {
// return SolarisVirtualMachine.class;
}
throw new IllegalStateException("Cannot use Attach API on unknown OS: " + osName);
}
private static String getProcessIdForRunningVM() {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
int p = nameOfRunningVM.indexOf('@');
return nameOfRunningVM.substring(0, p);
}
private String getHelpMessageForNonHotSpotVM(String vmName) {
String helpMessage = "To run on " + vmName;
if (vmName.contains("J9")) {
helpMessage += ", add <IBM SDK>/lib/tools.jar to the runtime classpath (before jmockit), or";
}
return helpMessage + " use -javaagent:" + jarFilePath;
}
private static VirtualMachine attachToRunningVM() {
String pid = getProcessIdForRunningVM();
try {
return VirtualMachine.attach(pid);
} catch (AttachNotSupportedException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void loadAgentAndDetachFromRunningVM(VirtualMachine vm) {
try {
vm.loadAgent(jarFilePath, null);
vm.detach();
} catch (AgentLoadException e) {
throw new IllegalStateException(e);
} catch (AgentInitializationException e) {
throw new IllegalStateException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment