5

I have two jar files. One.jar contains main method to start the process and other two.jar contains just class files.

In One.jar I have referenced two.jar in its manifest classpath.

One.jar contains mechanism to dynamically load the classes using Class.forName()

I want to deploy the One.jar only once for lifetime. Will not be making any changes to it.

Changes will be happening only in two.jar

I want to hot swap the two.jar with updated two.jar. I have seen other posts about hot swapping too like OSGi, hotswap for ANT but nothing helps me.

After a little research found out that JRebel does this really better but I really dont know how to integrate it with these jars? I am stuck on this for almost 2 days. Just need few steps of info to get this done. Someone help me please... This is really very important to me... Thanks

Sri777
  • 530
  • 3
  • 9
  • just drop the jar into the expected directory. if you are really just loading classes, if the jar is in your classpath, it will find the classes. Nothing fancy needed here unless your program is running 24/7 because then it wont release the classes from the jar. – SnakeDoc Jan 03 '14 at 21:49
  • 1
    To replace a class definition you need to have your own classloader to read two.jar. You then discard that classloader to get rid of the old jar in memory (as well as all its objects) and create a new to read the new jar. – Thorbjørn Ravn Andersen Jan 03 '14 at 21:50
  • @SnakeDoc I've not tried this under Java 7, but in Java 6 below, the JVM locks the files, making replacing them difficult...also, how would the JVM know that the Jars have being replaced? – MadProgrammer Jan 03 '14 at 21:52
  • edit: oops, thoughts @MadProgrammer was the OP! are you writing a program that runs 24/7? If the JVM terminates (program end), then the jars/classes should always be released. If your program runs 24/7 (like an application server, etc), then you will need something more industrial strength such as OSGi or JBoss/Glassfish, etc. But these are big heavy Java EE containers, and if your program isn't of that type, makes little sense to add all that overhead for this. – SnakeDoc Jan 03 '14 at 22:08
  • @SnakeDoc I just was hot swappable, which would discount just dropping in the Jars...Spent a lot of time writing a update process that could overcome this for our (very badly) written app - I'm just saying ;). Our solution is, stop, copy, start, which I assume is similar to what you are suggesting – MadProgrammer Jan 03 '14 at 22:14
  • @RomanVottner Yeah, that's kind of the way I would think about doing it to. The only issue is knowing when something changes and being able to drop the current class loader and load a new one...but that's all just context... ;) – MadProgrammer Jan 03 '14 at 22:14
  • 1
    @MadProgrammer right, that's what I was suggesting so long as the application doesn't need to run 24/7 (like some maintenance period, etc). Obviously a low-tech solution. Another way would be to implement a "staging" directory, drop your new jar into that one, and have a folder watcher service scan that directory every so often, if a jar is found, unload the previous one, remove it, copy the staging area jar over, load it via a class loader. This way you could also isolate the "innards" of your program from users a little more too. – SnakeDoc Jan 03 '14 at 22:22
  • @SnakeDoc I can surely say that this is a kind of bug in Java 7. I am trying to do this on Windows platform and I think it is locking the jar file. Even strange thing I have seen is I cannot delete the two.jar while JVM is running since it is locked but I can replace it with updated two.jar and the changes are not shown. – Sri777 Jan 05 '14 at 16:22
  • @RomanVottner So do you think if I hot swap a jar file on linux platform the changes would take effect? – Sri777 Jan 05 '14 at 16:24
  • @ThorbjørnRavnAndersen Thank you for your suggestion. Can you help me with little code on this please? I have tried System.gc() and even disabling the memorymap variable... nothing works for me. – Sri777 Jan 05 '14 at 16:26
  • @MadProgrammer and all other guys, I really want to thank you for your valuable responses to my question. As this is my first question in Stack overflow and I thought responses will be minimal but this is awesome. Thanks again for helping me :) – Sri777 Jan 05 '14 at 16:30

2 Answers2

5

Hey all I have finally got a solution for this. I really don't know that I will come up with such a easy solution. I took the idea of @Thorbjørn Ravn Andersen. All I did was first get the timestamp of the jar file and then load the jar using URLClassLoader. If the timestamp of the jar file changes (i.e. when I replace the jar with updated jar) then I am discarding old URLClassLoader object using close() and loading the new jar with URLClassLoader again. The only thing I have to check every time is whether the timestamp of jar changes or not. Hope this answer helps other people too. Thank you all for your support.

Sri777
  • 530
  • 3
  • 9
2

As I am directly related to JRebel (I'm the product manager), I probably can give some pointers for configuration.

To update the classes within a JAR with JRebel, place a dedicated rebel.xml configuration file into that two.jar which will point to the directory where the compiled classes of two.jar are.

     one.jar ---> two.jar
                   `- rebel.xml   // points to two/project/classes

Here's the doc with the examples: http://manuals.zeroturnaround.com/jrebel/standalone/config.html#configuring-jars

Depending on how your project is set up, the IDE plugins would help automating this.

Please note that if your intention is to do this procedure in live system, then JRebel is not a tool for this kind of purpose.

Anton Arhipov
  • 6,479
  • 1
  • 35
  • 43
  • Thank you Anton for the answer. Yea my project will go live in few days and thats why we are thinking of hot deployments to save time. If you think JRebel is not the tool for me then please can you suggest me any other one? – Sri777 Jan 05 '14 at 16:32
  • JRebel doesn't remote the technical limitations of the JVM platform in regards to hot deployment on live systems. It is designed purely as a development tool and the EULA restricts its use in production. There is another tool by the same vendor -- LiveRebel (http://zeroturnaround.com/software/liverebel/) which is aimed at application deployment automation, so you may want to take a look. If interested, ask for the demo via the website. – Anton Arhipov Jan 05 '14 at 18:51
  • @AntonArhipov just to put things straight - could you state your affiliation with JRebel in your answer? – Thorbjørn Ravn Andersen Jan 05 '14 at 18:55
  • @ThorbjørnRavnAndersen done (though, it is in my profile anyway) – Anton Arhipov Jan 05 '14 at 18:59