What do you mean by unload the agent? You cannot unload the classes as it implicitly says in the documentation:
the specified JAR file is added to the system class path (of the target virtual machine)
The only way arround this might be some custom class loader magic, but I would not recommend that.
Update: After looking at your extended question, I think your problem is actually something else. At some point you are invoking
JMXConnectorFactory.connect(new JMXServiceURL(GlobalVariables.connectorAddress))
in order to create a JMXConnector
. I guess that within your GlobalVariables.server.invoke
call, you are registering a MBean by new ObjectName("transformer:service=DemoTransformer")
. This name must be unique and when you are running the code a second time, this name is already taken as suggested by javax.management.InstanceAlreadyExistsException: transformer:service= DemoTransformer
. What you needed to do is:
- Either choose another name when registering the MBean a second time.
- Call
MBeanServerConnection.close(new ObjectName("transformer:service=DemoTransformer"))
before detaching from the remote JVM in order to make the name available again.
You might have assumed that by detaching, all state on the remote machine was reset. This is however not true. You added an MBean with a name and than you tried to do this again. This error can be understood as if you added a two values with the same key to a map. Other than with the map, you will however not override values but cause the exception you observe above.
By the way: You should call JMXConnector.close
explicitly when the connection to the remote server is not longer required.
PS: You might find this article interesting.
Update 2: After discussion in the chat and after getting the MBean naming conflict out of the way, I think this is what caused the problem:
When a Java Agent is loaded a second time, the classes that come with the agent (represented in managementAgentJarFile
) are already loaded in the target JVM. This means, that no class initializers will be run again and state changes that are represented by static
variables will still be represented. Additionally, it is not possible to load classes with the same name but changed implementation. This will cause LinkageError
s and the agent loading will fail. The solution is to avoid static
state such that an agent cannot inflict with itself and to create separate name spaces for different agents. Otherwise, agent classes can be unloaded by using custom class loaders. More information on this matter can be found on many places and here: