Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a JAR whilst running

Given a jar runs within a JVM would it be possible to unload the current running Jar and remove it from the system. Download a new version and rename it with the same name of the last Jar and then initialise the new Jar, creating a seamless update of the Jar within the JVM. Is it even possible to instruct the JVM to perform this action? Is it even possible to update a Jar whilst its running?

like image 641
James Moore Avatar asked Jun 25 '11 11:06

James Moore


2 Answers

Download a new version and rename it with the same name of the last Jar and then initialise the new Jar, creating a seamless update of the Jar within the JVM ... Is it even possible to update a Jar whilst its running?

The JAR file is not 'running', the JVM is running. Your JAR file just contains the class information (aka byte code instructions) that make the JVM do useful work. In most cases the JVM will actually not put a system lock on your JAR file, so you can replace that file to your hearts content.

The real problem of course is that once the JVM loads your JAR it will carry along happily with what it loaded and never read from your JAR file again, no matter how many times you overwrite it. This is the behavior of the default class loader and cannot be changed - however as others have pointed out - you do NOT have to use the default class loader. You can implement your own, similar to what Web Application Servers use, in order to load updated JARS from the filesystem. Caveat though - defining your own classloader is considered a 'Bad Idea™' unless you really know what your doing. You can read more here and here.

like image 171
Perception Avatar answered Nov 14 '22 11:11

Perception


This is something that I've seen done many times before (and also done myself). I composed some points of the problems/solutions that might arise.

  • JVM will crash with a dump if you overwrite a JAR file that it will use later on.
    • By later I mean classes are loaded quite lazily and some might only be loaded later in your program's life
    • JVM has an open handle for the JAR file and the lib will fail as the JAR and pointers become wrong
    • The probability can be decreased by pre-loading all classes and resources from the JAR file
    • If you have a custom classloader then you can close the handles yourself.
  • You will need to know about how class loading is done. Better yet be in control.
    • A custom classloader that will create a classloaders per JAR and manage the versioning
    • Know how your application uses classloaders and how it acts on new JARs (for example check what Tomcat does when you overwrite a WAR archive)
  • On Windows your JAR files will be locked and you cannot overwrite them. If you are in control then you can unlock them after use (close them). For 3rd party systems you have to find the respective flags. For example you can check the antiJARLocking in Tomcat context configuration.
  • Always better to avoid overwriting the same file and rather have some versioning going on

All in all there are many issues that you might run into when you want to achieve JAR reloading. Luckily there are ways how to minimise the risks. The safest way is to do something similar to get the same effect. Cleanest is custom classloaders and JAR file versioning.

like image 30
toomasr Avatar answered Nov 14 '22 11:11

toomasr