Imagine writing java code hit Ctrl+S and then click refresh on browser, voila the changed java code actually works!! Or in server environment you made a slight change to a class file. Wish it were loaded without require of a server restart. Or you changed some resource properties file, did you imagine that your changed resource properties file will also require a server restart. It would be nice if all web applications worked this way out of box.
Well, there is a way to make web applications reload each time it detects a change in resources. There are two ways an app server can help in reloading changes.
- Auto-reload (Reloads the changed files and classes and then re-initialize the application, which may take another 30sec to 1 min. All the servlets that load on startup are restarted, caches cleared and reloaded. This is almost takes the same time as restarting tomcat.)
- Hot Swap of classes - Provided by JDK class redefining without class reloading, but this works only in debug mode Java Platform Debugger Architecture (JPDA) . This can be done in tomcat running inside eclipse or other IDE. This requires tomcat to run in debug mode in eclipse). This article http://blog.redfin.com/devblog/2009/09/how_to_set_up_hot_code_replacement_with_tomcat_and_eclipse.html describes the setup of doing this with eclipse and tomcat.
- FastSwap (websphere) only available in WebLogic (http://docs.oracle.com/cd/E15051_01/wls/docs103/deployment/deployunits.html ). This is better than Hot Swap, it is not only limited to changes in the method body. It also does not user a new classloader. I am not sure how it does the trick, I have never used it also, but wish it was there in tomcat too :( .
Tools that do class reloading:
- JRebel http://zeroturnaround.com/jrebel/
- fakereplace http://github.com/fakereplace/fakereplace - words in web apps too.
- Javeleon javeleon.org - As of today April, 2012 it does not work in web applications. But when I asked them they replied that it is coming soon :).
- DCEVM Dynamic Code Evolution VM http://ssw.jku.at/dcevm/
- AgentSmith http://java.net/projects/agentsmith - Uses java instrumentation and class redefining. However this project is not maintained, but it consists of only 3 classes.
- Apache common-jci-fam http://commons.apache.org/jci/commons-jci-fam/index.html
Frameworks which helps or does class reloading:Grails, play framework, tapestry, spring scripted beans, struts2 by using struts-spring-plugin, OSGi, struts2 OSGi plugin.
Oracle's PL/SQL- Make the front end generic, everything in configuration files, and push all the logic including gui validation to PL/SQL. Believe me this is possible and I have seen it. PL/SQLs can be compiled anytime.
Class Reloading Methods
(disclaimer: I am not an expert in jvm, neither I am expert in class loaders. So whatever I am going to say is based on my research of few other blogs, inspection of code struts spring plugin which does class reloading.)
Most I have seen two ways of class reloading, which are using java (a) HotSwap or (b) java ClassLoaders.
The main problems that makes class reloading hard in jvm level are bytecode optimisers and jvm JIT compiler and multi generation garbage collection. I will not go too much deep into jvm internals but I would certainly point to a blog which explains about class reloading in webapps, OSGi in general http://zeroturnaround.com/blog/rjc301/. This is another blog which discusses about why jvm hotswap is limited only to method bodies modification http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/, this blog has a really inspiring video "A video presentation 'Do you really get class loaders' by Jevgeni Kabanov followed by a nice example of the very basic class reloading in action.
While implementing the various class reloading methods I faced some issues so I intend to show the complete setup here so that you can get a feel about it.
1. Hot Swap using AgentSimth URL: http://classreloadingwebapp.blogspot.com/2012/04/class-reloading-using-agentsmith.html.
2. Fakereplace- Using fakereplace in a webapp is really simple. Just add the following to JAVA_OPTS
in catalina.sh or catalina.bat if you are running tomcat. -javaagent:C:/Users/Samarjit/Desktop/fakereplace-parent-0.9-bin/fakereplace/fakereplace.jar -Dorg.fakereplace.packages=view
4. Struts2 Spring plugin with class reloading- This is simple and words well out of box as per instructions. I figured out that it is using apache-commons-jci-fam. But they have integrated with springs so tightly that you will not get who is doing the trick of class reloading. After digging deep into it I decided to give apache-commons-jci-fam a try without even a sprinkle of spring. That makes my next project
5. Apache-commons-fam-jci - They have examples but those requires a bit of configuration to get them running. So I created a project that can be just checked out and run. They simulate JSP container. It reads JSP from plain text HTML then created a java source of it and compiles and finally loads the class, all of this happens on the fly and you do not need to restart your servlet container. If they can work with JSP we can apply the same to normal java classes and servlets too. URL: http://classreloadingwebapp.blogspot.com/2012/04/class-reloading-using-apache-commons.html
5. Struts2 OSGi plugin - Again this plugin seems not to be used by anyone. As there are hardly any documentation, also the plugins page does not show how to implement it with and without springs. Somehow its mixed up in the document. So I created a project completely without springs. Where you can get a feel of just the OSGi plugin. URL: http://classreloadingwebapp.blogspot.com/2012/04/class-reloading-4-using-struts2-osgi.html