Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javaagent class unloading

I have a java agent which instruments bytecode. I am using the attach apis in java 6 to allow users to dynamically load the agent and instrument and deinstrument code using my java agent. I am using the Boot-Class-Path manifest attribute to make sure my javagent classes are in the boot classpath so that my users can instrument classes like ArrayList, etc.

However the problem comes with versioning. Lets say a user dynamically attaches version 1 of my agent. Then I given him version 2. Now since his app server never shut down since he attached version 1 of my agent, the version 1 classes are still loaded.

I need some way such that when my client version 2 of the javaagent, the version 1 is unloaded.

I know one way would be to write a customer classloader for my javaagent's classes, and set the classloader reference to null. However in that case I wont be able to instrument classes in the boot classpath since my classloader will be below in the hierarchy from the boot classloader and thus my users cant instrument classes like ArrayList because if I add a call inside ArrayList's methods to one of my agent's classes' methods the boot class loader wont be able to see them.

So is there any way to solve the boot classpath issue and still unload the previous agent's classes?

like image 849
pdeva Avatar asked Aug 14 '26 21:08

pdeva


1 Answers

I'm not an expert on this topic, but it seems like this kind of unload-to-replace is not directly supported.

But do you need to unload-replace the class?

Could you instead create a never-changing class that the external world talks to, in which you internally imlpement a versioning system?

For example, you create class MyToolAgent that has, say, a static string with the classname of the ToolAgentImplementation to use. When you first release, it's set to use ToolAgentImplementation1_0. When you upgrade to version 2.0, you deploy an additional class called ToolAgentImplmenetation2_0, and update the MyToolAgent class to load and use it. You never unload version 1.0, but you do stop using it. You do waste some memory here, but you achieve the version upgrade.

I don't know if this is feasible in your situation, but in general it seems the JVM doesn't support directly swapping in a new version, but that you should be able to hide that in some way.

like image 80
rice Avatar answered Aug 17 '26 12:08

rice