Is it possible to insert a javaagent after virtual machine start from within the same VM?
Lets say for example we have an agent in a jar myagent.jar with the appropr
You should be able to do it in Java 6, see the package documentation chapter "Starting Agents After VM Startup"
edit: Maybe it was possible in Java 5 already and just the javadocs didn't mention it that explicitly
https://web.archive.org/web/20141014195801/http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/ has a great example of how to write an agent as well as how to start one on the fly.
Yes, you just have to pass the JVM process ID to the VirtualMachine.attach(String pid)
method, and load the agent jar. The VirtualMachine
class is available in the JDK_HOME/lib/tools.jar file. Here's an example of how I activate an agent at runtime:
public static void attachGivenAgentToThisVM(String pathToAgentJar) {
try {
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
String pid = nameOfRunningVM.substring(0, nameOfRunningVM.indexOf('@'));
VirtualMachine vm = VirtualMachine.attach(pid);
vm.loadAgent(pathToAgentJar, "");
vm.detach();
} catch (Exception e) {
e.printStackTrace();
}
}
Having encountered the same issue, I have found a far more comprehensive solution, from the ByteBuddy library.
ByteBuddy thoroughly attempts to load its java agent dynamically:
Installs an agent on the currently running Java virtual machine. Unfortunately, this does not always work. The runtime installation of a Java agent is supported for:
- JVM version 9+: For Java VM of at least version 9, the attachment API was moved into a module and the runtime installation is possible if the {@code jdk.attach} module is available to Byte Buddy which is typically only available for VMs shipped with a JDK.
- OpenJDK / Oracle JDK / IBM J9 versions 8-: The installation for HotSpot is only possible when bundled with a JDK and requires a {@code tools.jar} bundled with the VM which is typically only available for JDK-versions of the JVM.
- When running Linux and including the optional junixsocket-native-common dependency, Byte Buddy emulates a Unix socket connection to attach to the target VM.