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:
JavaRebel1.1 comes up with the following features:
Changing method bodies
Adding/removing implemented interfaces
- 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
- 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
Normal Deployment Process:
Typical JEE developer spends his day in the development-compile-deploy-test cycle.
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.
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.
Hence the below best benefits can be reaped using JavaRebel
Add the following to JVM command line (note that it is important that the JAR would be named “javarebel.jar”)
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
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
The installation for Java 1.4 has two parts:
- Generating a bootstrap jar
- Adding command line options to the JVM
java -jar /path/to/javarebel.jar will generate a
javarebel-bootstrap.jar. This file is generated to the folder where
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!
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.
JavaRebel requires the
javarebel.jar to be prepended to the Java bootclasspath as well as the
-noverify JVM flag:
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
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
Configuring properties related to JavaRebel can be done in two ways:
a) Global Configuration
b) Using rebel.xml
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.
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.
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.
Enables support for bypassing bytecode-based proxies created with CgLib or Javassist.
Set this to absolute path of the plugin jars to enable 2.0 plugins.
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.
Enables additional logging of the performance statistics to the JavaRebel.log file. Requires JDK1.5+.
Enables trace logging to the JavaRebel.log file. Generates a very detailed, but extremely big log.
Disables all JavaRebel output to standard output, e.g. the console
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.
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.
The contents of the
rebel.xmlis defined by the schema attached herewith: