Oct 13, 2009

Java Rebel - On the fly class reloading

Introduction

JEE development, though challenging and exciting, most of the JEE developers are vexed of redeploying the application, restarting the container even for a small change in the code. This eats up major development time of the developers causing lesser productivity, increase in resource count, project cost, schedule and many more.

When we think of the present day programming era, lots of technologies evolved to facilitate the software developer program development easier. But still we could see most of the developers (Java developers especially) struggling to deploy, restart container for little changes in the code. In a thought to kick this overhead from the developer’s shoulders and improve development productivity and overall project cost, ZeroTurnAround team has come up with an archive on the name JavaRebel which helps developers during program development changes.

Digging Java Rebel

JavaRebel is a JVM plugin that enables reloading the changes made to Java class files on-the-fly, hence saving developers’ time to redeploy an application or perform a container restart. It is a generic solution that works for Java EE and Java standalone applications.

JavaRebel installs as a JVM plugin (-javaagent) and works by monitoring the timestamp of class files. When a class is updated (e.g. when a developer saves a class from the IDE) JavaRebel will reload the changes to the class code and structure while preserving all existing class instances. This means that changes to classes and configurations can be seen immediately, without the need to redeploy an application or perform a container restart - typically saving 5-10 minutes per hour of development time. The loading is lazy and will happen upon usage of the class (method call on an instance, static call on the class, field lookup etc).

JavaRebel brings Ruby and PHP style dynamic reloading of classes to Java. While it currently has several limitations it can speed up development dramatically.

The following classes will be reloaded when they are changed and compiled:

  • All “.class” classes inside the usual classpath (WEB-INF/classes, etc). Using this with exploded deployment will provide the best JavaRebel experience.
  • All “.class” files in directories specified by -Drebel.dirs (comma-separated list) JVM command line property. With this you can deploy in unexploded development mode (EAR or WAR) and still reload classes instantly. For example -Drebel.dirs=/path/to/eclipse/project-one/bin, /path/to/eclipse/project-two/bin. However new classes (or renamed old classes) will not be loaded before they also appear in the classpath (e.g. after the build in JAR files).

One of the selling points of PHP, Ruby, Python and other interpreted languages is their faster development. This is not based on the superiority of the language constructs, but instead on the minimal turnaround time in development environments. JavaRebel aims to provide the same productivity in Java.

In short the below two figures show what JavaRebel does:

clip_image002

clip_image004

Features of JavaRebel

JavaRebel1.1 comes up with the following features:

 

JavaRebel

Changing method bodies

clip_image005

Adding/removing methods

clip_image005[1]

Adding/removing constructors

clip_image005[2]

Adding/removing fields

clip_image005[3]

Adding/removing classes

clip_image005[4]

Adding/removing annotations

clip_image005[5]

Changing interfaces

clip_image005[6]

Replacing superclass

clip_image006

Adding/removing implemented interfaces

clip_image006[1]

Supported JVMs

  • Sun Java 1.4.x
  • Sun Java 5.x
  • Sun Java 6.x
  • JRockit JVM 8.1sp6 or later
  • JRockit JVM 9.x 1.5.0_06 or later
  • IBM J9 1.4.x
  • IBM J9 5.x
  • IBM J9 6.x
  • Apple MRJ 5.x
  • Apple MRJ 1.4.x
  • Apple MRJ 5.x

Supported Containers

  • IBM WebSphere
  • BEA Weblogic 8.x, 9.x, 10.x
  • GlassFish v2
  • Oracle OC4J 9.x, 10.x
  • Tomcat 4.x, 5.x, 6.x
  • JBoss 3.x, 4.x (on Java 5 or later)
  • Jetty 5.x, 6.x (on Java 5 or later)
  • Equinox OSGi (including Eclipse plugins)
  • IntelliJ IDEA plugins

Benefits

Normal Deployment Process:

Typical JEE developer spends his day in the development-compile-deploy-test cycle.

clip_image008

As developers perform this cycle several times a day it is a significant loss to SWD departments, additional risks appear and developers typically get bored.

Using JavaRebel:

As opposed to usual deployment process JavaRebel does not spend any time on reinitializing the application and does not interrupt the developer routine. Instead it reloads the code for updated classes only and continues to run application as is.

clip_image010

Hence the below best benefits can be reaped using JavaRebel

clip_image012

Installation

Java 5 or later

Add the following to JVM command line (note that it is important that the JAR would be named “javarebel.jar”)

-noverify -javaagent:/path/to/javarebel.jar


Windows examples




  • java -noverify -javaagent:C:\libraries\javarebel.jar -Drebel.dirs=c:\workspace\project\classes com.domain.Application


  • java -noverify -javaagent:C:\libraries\javarebel.jar -Drebel.dirs=c:\workspace\project\classes -jar application.jar



Linux examples




  • java -noverify -javaagent:/home/john/libs/javarebel.jar -Drebel.dirs=/home/john/workspace/project/classes com.domain.Application


  • java -noverify -javaagent:/home/john/libs/javarebel.jar -Drebel.dirs=/home/john/workspace/project/classes -jar application.jar





Java 1.4.x


The installation for Java 1.4 has two parts:





Generating the bootstrap jar


Running java -jar /path/to/javarebel.jar will generate a javarebel-bootstrap.jar. This file is generated to the folder where javarebel.jar resides.



IMPORTANT! javarebel-bootstrap.jar is JVM and JavaRebel version specific! If you upgrade your JVM (even a minor version) or upgrade JavaRebel you have to regenerate javarebel-bootstrap.jar.



IMPORTANT! Make sure that the JVM version used to generate javarebel-bootstrap.jar is the same your application will run with!



Example




  • java -jar C:\libraries\javarebel.jar - will generate a javarebel-bootstrap.jar into the folder C:\libraries\


  • java -jar /home/john/lib - will generate a javarebel-bootstrap.jar into the folder /home/john/lib



NOTE The easiest way to ensure JVM and JavaRebel version consistency is to add the javarebel-bootstrap.jar generation to the startup script of your application server. This means that on every startup the javarebel-bootstrap.jar is generated with the JVM that is used to start the server. This is an inexpensive invocation and will not be noticeable.



Adding command line options to the JVM


JavaRebel requires the javarebel-bootstrap.jar and javarebel.jar to be prepended to the Java bootclasspath as well as the -noverify JVM flag:



-noverify -Xbootclasspath/p:/path/to/javarebel-bootstrap.jar:/path/to/javarebel.jar


Windows examples




  • java -noverify -Xbootclasspath/p:C:\libraries\javarebel-bootstrap.jar;C:\libraries\javarebel.jar -Drebel.dirs=c:\workspace\project\classes com.domain.Application


  • java -noverify -Xbootclasspath/p:C:\libraries\javarebel-bootstrap.jar;C:\libraries\javarebel.jar -jar -Drebel.dirs=c:\workspace\project\classes application.jar



Linux examples




  • java -noverify -Xbootclasspath/p:/home/john/libs/javarebel-bootstrap.jar:/home/john/libs/javarebel.jar -Drebel.dirs=/home/john/workspace/project/classes com.domain.Application


  • java -noverify -Xbootclasspath/p:/home/john/libs/javarebel-bootstrap.jar:/home/john/libs/javarebel.jar -Drebel.dirs=/home/john/workspace/project/classes -jar application.jar





Configuration



Configuring properties related to JavaRebel can be done in two ways:



a) Global Configuration



b) Using rebel.xml



a) Global Configuration



JavaRebel can be configured using Java system properties or the SDK API. To find out more about the configuration API please visit the SDK home and the API Javadoc. A description of available system properties follows.



-Drebel.packages=PACKAGE1,PACKAGE2,...



This should be set to a comma-separated list of Java packages. JavaRebel will then only reload classes in those packages and their subpackages. This is mainly used to restrict reloading to only a limited subset of classes, e.g. to improve performance.



-Drebel.packages_exclude=PACKAGE1,PACKAGE2,...



This should be set to a comma-separated list of Java packages. JavaRebel will not reload classes in those packages and their subpackages. This is mainly used to exclude classes that produce errors with JavaRebel reloading. JavaRebel will reload classes that are not in the exclude packages and are in an include package. By default all .class classes will be reloaded.



-Drebel.allow_bytecode_proxy=true



Enables support for bypassing bytecode-based proxies created with CgLib or Javassist.



-Drebel.plugins=jar1,jar2,jar3,...



Set this to absolute path of the plugin jars to enable 2.0 plugins.



-Drebel.log=true



Enables debug logging to the JavaRebel.log file. Use when you are having some problems with the JavaRebel and you need to get more context.



-Drebel.log.perf=true



Enables additional logging of the performance statistics to the JavaRebel.log file. Requires JDK1.5+.



-Drebel.log.trace=true



Enables trace logging to the JavaRebel.log file. Generates a very detailed, but extremely big log.



-Drebel.log.stdout=false



Disables all JavaRebel output to standard output, e.g. the console





b) Using rebel.xml



rebel.xml gives the developers a well defined and easily interpreted fine-grain control in dynamic reloading of changed classes. It supports <jar/>, <jarset/>, <dirset/>, <war/> and many more which help developers configure JavaRebel to perform its best.



Starting with JavaRebel 2.0 rebel.xml file must used for web applications that use packaged deployment (i.e. WARs, JARs and EARs). Instead of the WAR/JAR/EAR file deployed all resources will be picked up from the locations provided in the rebel.xml. Also these directories and archives will be monitored for changes.



The rebel.xml must be placed in the WEB-INF/classes directory of the deployed WAR file. For class path configuration rebel.xml can also be placed in a root directory of a JAR file or in the root of EJB JAR modules. A rebel.xml file should be provided per each module in the application that you want to change on-the-fly.



The contents of the file are divided into the following sections:



classpath - directories and JARs used for classes and other classpath resources.



web - directories and JARs used for Servlet Context resources such as JSPs as well as static resources.



war - directory or WAR file being the root of the whole web application.



A sample configuration file with documentation is below. This file can be copied to your project and appropriate sections deleted or customized.



clip_image014



The contents of the rebel.xml is defined by the schema attached herewith:


clip_image016



References:



0 comments:

Text Widget

Copyright © Vinay's Blog | Powered by Blogger

Design by | Blogger Theme by