Lightning fast portlet development with JRebel

Back in April of this year I had the opportunity to speak at the CON-FESS conference in Vienna, Austria. One of the exhibitors there was zeroturnaround.com and I had the privilege of sitting next to founder Jevgeni Kabanov over dinner one night.

Jevgeni described the benefits of JRebel, a JVM-plugin that makes it possible for Java developers to instantly see any code change made to an app without redeploying. Needless to say, redeploying WARs is part of the very fabric of a Liferay portlet developer's life, so I knew that I had to give this product a try with my next ICEFaces 2 portlet with PortletFaces Bridge.

and to my utter amazement... IT WORKED!!!

Simply put, this product is a MUST HAVE for Liferay portlet developers. I'm hooked! Over the past 6 years of portlet development, this product could have saved me COUNTLESS hours of development time waiting for redeploys.

The JRebel documentation is quite good, but here are some quick instructions for how to get started with JRebel and the Liferay+Tomcat bundle:

  1. Download JRebel (30 day free trial)
  2. Install JRebel to it's default location. For example, on the Mac: /Applications/ZeroTurnaround/JRebel
  3. Set the REBEL_HOME environment variable. On the Mac, I find it's best to do this inside the $HOME/.MacOSX/environment.plist file:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0"> <dict>
    <key>REBEL_HOME</key>
    <string>/Applications/ZeroTurnaround/JRebel</string>
    </dict>
    </plist>
  4. On Mac, add the following to the LIFERAY_HOME/tomcat/bin/setenv.sh script:
    -javaagent:$REBEL_HOME/jrebel.jar
  5. On Windows, add the following to the LIFERAY_HOME/tomcat/bin/setenv.bat file:
    -javaagent:%REBEL_HOME%\jrebel.jar
  6. Create a rebel.xml file that will be deployed in the runtime classpath of the WAR:Note that if you install the JRebel plugin for Eclipse, IntelliJ 8/9, IntelliJ X, or NetBeans) you can right click on the project and have the IDE generate the file. You can also generate the rebel.xml file with a Maven goal.
    • Maven: src/main/resources/rebel.xml
    • Liferay Plugins SDK: docroot/WEB-INF/src/rebel.xml
  7. Start Tomcat with the liferay/tomcat/bin/startup.sh script (startup.bat on Windows)
  8. Deploy the WAR to the Liferay /deploy folder
  9. Make some Java code changes to your app and click Save in your IDE
  10. Reload your browser, and voila! Instant changes! No redeploy!

 

Blogs
It sounds very interesting. I will give it a try. Thank you!
After some testing I must say, this is amazing! I am going to test it a bit deeper to see, whether it is usable for production and stable with different enviroments. If yes, then it is a huge move forward especially for portal development!
This is good...thnx for Sharing...
Can we achieve the same for extension environment, apart from using reloadable=true?
Since Liferay lives in a web application context (for example, webapps/ROOT under Tomcat), then JRebel should work just fine for EXT plugins. You would just need to add a rebel.xml file to the web application context in which Liferay is deployed.
[...] If you look for official info in our documentation about JRebel supporting Liferay, you will not find it yet; we are working towards getting this more formalized in future JRebel releases. However,... [...] Read More
Hi Neil, I tested JRebel myself just using the JRebel documentation offered during installation (which is really excellent I must say) and got Liferay working with JRebel and making use of the MVCPortlet as the base. Both the presenation jsp as well as the java classes are now instantly reloaded on the save of the content, but changing configuration files such as liferay-portlet.xml and portlet.xml still require a restart. Is this the same with you?
Regardless of this: JRebel seems to really speed up the development cycle that is sure. So thanks for this very inspiring post!
Hi Petros,

I thinks this is ok, since these deployment descriptors are checked by each deployment of a plugin and thus the plugin must be re-deployed in order to see changes in mentioned descriptors. Anyways it would be nice to have a plugin for Liferay to enable hot-swap of these descriptor. I am not sure whether it will be possible on the Liferay part.
@Petros: Jan is right -- it would be really nice to have portlet.xml and other descriptors get reloaded as well, but it is something I think we can live with. Perhaps this is something the folks at zeroturnaround.com could investigate as a feature.
Actually, we have used this for years emoticon
@Sampsa: Great to hear. JRebel must be the world's best kept secret!
@Jan and Neil: thank you for the info. I can definitely live with this, as these changes don't occur al that often after all. I just wasn't sure if I might have made some JRebel configuration error. emoticon
I am definitely recommending JRebel from now on as is. :-)
Hi Neil, thanks for the great post. I do have a slight problem though and was wondering if anyone else is in the same situation:

I do have the application running in the debug perspective of eclipse and starting with the registered server there, not with the bin/startup script. I disabled the automatic publishing, as it is recommended by the jRebel Feature.

The class changes are working just fine, but any jsp changes don't get deployed. Any help on that.

Thanks a lot.
[...] If you look for official info in our documentation about JRebel supporting Liferay, you will not find it yet; we are working towards getting this more formalized in future JRebel releases. However,... [...] Read More
Hi,

Just downloaded jrebel eclipse plugin.
I also use Liferay IDE plugin for Eclipse.

Everything goes smooth during jrebel plugin installation. Then I add my liferay server to jrebel managed servers through the JRebl perspective. The java agent seems to ben installed , as I can see the following log lines :

============================================================
JRebel: Starting logging to file: C:\Documents and Settings\utilisateur\.jrebel\jrebel.log
[2012-07-02 08:20:28]
[2012-07-02 08:20:28] #############################################################
[2012-07-02 08:20:28]
[2012-07-02 08:20:28] JRebel 5.0.0 (201206080930)
[2012-07-02 08:20:28] (c) Copyright ZeroTurnaround OU, Estonia, Tartu.
........
#############################################################


Next step, I add the jrebel nature to one of my portlet projects. The rebel.xml file is created,, with the classpath configuration pointing to the WEB-INF/classes of the project in the plugin SDK.

But when I alter my portlet class, nothing happen in the portal : the class is compiled by the IDE in ${pluginSDK}/portlets/myproject/docroot/WEB-INF/classes, but never deployed to my app server.

Am I missing something here ?
I would recommend that you do the following:
1. Right click on your portlet project, and left click on Properties
2. Click on Java Build Path
3. Click on the Source tab
4. Make sure that the "Default output folder" text field has the same value as the <classpath> <dir> entry in rebel.xml
THat was some one and a half year a ago, but I'll give it another try :-)

Thanks for the tip.