views:

511

answers:

5

how to unload a class from the class loader so that i can use the recently changed class on the fly without restarting my application(hot deployment). is it possible to do that.

+2  A: 

You can't unload a class that is actually in use. But you might want to have a look at platforms like OSGi, if you want to reload or redeploy your application during runtime.

PartlyCloudy
A: 

Java rebel reloads changed classes on the fly. See the jrebel website for details. I don't know that I would recommend this for a production environment though, because of performance issues. JRebel on occasion bogs things down momentarily when you've recompiled for a server.

Jim Barrows
+5  A: 

To unload a class you have to create a custom classloader and load the class using it. Tomcat does it and so does JRun. You can look in Tomcat code for an example.

After you are done with the class you need to release all references to the class as well as to the class loader by reassigning the variables or setting them to null.

Then either wait for System.gc() to unload the class or you call it directly in a loop till no more bytes can be freed. however normally calling it twice does the trick.

Note: You cannot unload a single class. You have to unload the classloader along with it. So obviously System classloader is not the suitable for this task

giri
Calling System.gc() isn't relyable, shouldn't it be enougth to load the class with a new class loader instance?
josefx
+1  A: 

You can't explicitly unload a class.

In principle, you can expicitly reload a class via Classloader.loadClass(). From that moment onwards, all new instances of that class will use the new definition.

In any case, I would proceed with extreme caution...

Neil Coffey
A: 

You would have to create a custom ClassLoader: which returns all Objects wrapped inside a Proxy. The ClassLoader must have a list of all referenced Proxies (keep this list WeakReferenced). If you decide to "unload" and thus "reload" any class, you wait untill the class is loaded, find all Proxy's in your list, and replace the actual object.

There are several problems: you need Reflection, to get all private variables and reset the internal state (see setAccesible on Field). Also multi-threading problems might occour, thus the Proxy must be synchronized: which makes it performing poor.

You can better look for Google's Guice dependency solution, which enables unplugging and reloading modules at runtime. This might be a solution, but way too bloated for a small app. Still: I'm not sure wheter the GC also unloads unused classes.

Pindatjuh