Reputation: 1793
I have created a java agent jar file (which works perfect on command line). Next I would like to attach this agent to a running JVM in a j2ee server. So I used the code:
public static void loadAgent() {
System.out.println("dynamically loading javaagent");
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
int p = nameOfRunningVM.indexOf('@');
String pid = nameOfRunningVM.substring(0, p);
try {
VirtualMachine vm = VirtualMachine.attach(pid);
String jarFilePath = vm.getSystemProperties().getProperty("java.home")+File.separator+"lib"+File.separator+"test-agent-7.jar";
vm.loadAgent(jarFilePath, "");
vm.detach();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
EDIT: This is now working, and I am able to see that Transformer is called. I can also remove the transformers and been able to debug the transformers.
My question is:
Upvotes: 3
Views: 3193
Reputation: 3592
Well, there is several things to consider:
If you load the agent, you load the classes. As long as the related class loader is in the memory of the Java VM, the associated classes will stay loaded. I do not think you can prevent / circumvent that easily. But this should be only a small memory overhead which you incure by loading an agent.
A bit of research indicates that the agent will be loaded by the SystemClassLoader, so unloading those classes will be impossible.
Starting Agents After VM Startup
An implementation may provide a mechanism to start agents sometime after the the VM has started. The details as to how this is initiated are implementation specific but typically the application has already started and its main method has already been invoked. In cases where an implementation supports the starting of agents after the VM has started the following applies: The manifest of the agent JAR must contain the attribute Agent-Class. The value of this attribute is the name of the agent class. The agent class must implement a public static agentmain method. The system class loader ( ClassLoader.getSystemClassLoader) must support a mechanism to add an agent JAR file to the system class path. Link to source
What you can influence however, is what the agent is doing.
You want to shutdown that agent? Provide a shutdown method.
If you want to stop an agent from outside, this agent could provide a JMXBean which shuts the agent down.
This method could then remove the transformers from the Instrumentation interface or stop whatever else the agent is doing inside the Java VM (free up references / resources which are held, so that the objects are garbage collected, stuff like this).
Without being a bit more specific on what you want to achieve, it is hard giving a better fitting answer.
Upvotes: 2