JRebel
Last updated
Was this helpful?
Last updated
Was this helpful?
Deploying code changes (Java-Classes, JSF-Resources, Spring-Context-Changes, ...) to the server is usually done this way:
This process takes - depending on the size of your application - some minutes ... several times a day.
In Java 1.5 the Hot-Swap mechanism was introduced but it is very restricted because it allows only method body changes during remote debugging sessions. When I used it it was not very reliable (sometimes it worked ... most often: not).
Spring-Boot supports Warm-Restart and also Jetty supports some kind of Hot-Swapping (but still limited - I have heard of).
JRebel supports real Hot-Swapping of a wide range of refactorings
http://zeroturnaround.com/software/jrebel/features/
It supports also a wide range of frameworks ... a lot of framework-specific refactorings (e. g. changing the spring context) are possible without restarting the application.
Video 1: (https://vimeo.com/112443042)
Video 2: (https://www.youtube.com/watch?v=4JGGFCzspaY)
There are some approaches to reduce this costs:
increase maven build and application server redeploy time
best idea - BUT: hard to reach
use test-driven development
very good idea: BUT: for some modules (e. g. webui) in some situations too much overhead
for JSF-UI-resources: configure Eclipse to work on JSF-resources directly
BENEFITS:
xhtml changes directly visible
DRAWBACKS
copy task back to the version controlled files needed (if you forget you loose code) works only for JSF resources .xhtml resources
configure application server to use the Eclipse attached source folders (under version control) or the maven generated resource folders (containing .class, .xhtml, .properties).
JRebel transforms your IDE into a deployment tool ... the artifacts created by your IDE are integrated into the running deployment (inside or outside of your IDE):
maven-jrebel-plugin:
rebel.xml:
http://manuals.zeroturnaround.com/jrebel/standalone/config.html
http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd
JRebel adapts the Classloading Mechanism of the running application. When the application loads a resource via Classloader the JRebel Classloader is used to check whether the resource under IDE-control (Eclipse, maven) is newer than the one deployed in the applications artifact (jar, war).
JRebels statement:
"JRebel versions each class individually, instead of an entire application or module at a time – and it does not use classloaders. With JRebel, changes to classes are always visible with the Reflection API." (http://files.zeroturnaround.com/pdf/JRebelWhitePaper2014.pdf)
If there is a resource in the back-referenced folder then JRebel uses this one. It uses the FIRST back-referenced resource it finds. If you would have two back-referenced resource folders (e. g. bin/classes and target/classes) it uses the first found (usually the one in bin/classes/MyClass.class). JRebel does not compare the timestamps of "bin/classes/MyClass.class" and "target/classes/MyClass.class" to use the most recent one.
THEREFORE: I recommend to only include the Eclipse target build folder (bin/classes) into the back-references. If you update your VCS-resources outside of your IDE (e. g. with a Command-Line-Tool) you should rebuild the updated projects also within your IDE (if it does not support automatic reload ... Eclipse has hooks for it).
... with one module - in 15 minutes ..
download and unzip software package (e. g. to ~/programs/jrebel
- aka JREBEL_HOME): https://zeroturnaround.com/software/jrebel/download/
download license file (e. g. put it into ~/.jrebel/ directory)
activate JRebel by:
$JREBEL_HOME/bin/activate.sh $PATH_TO_LICENSE_FILE
e. g. ~/programs/jrebel/bin/activate.sh ~/.jrebel/jrebel.lic
KEEP IN MIND: there is also an Actiivation-UI (if you do not like CLI)
JRebel provides an interactive script that adapts the tomcat startup scripts:
$JREBEL_HOME/bin/setup.sh -r $TOMCAT_HOME
e. g.: $JREBEL_HOME//bin/setup.sh -r ~/programs/apache-tomcat-7.0.42
ATTENTION: I had to adapt the created startup script startup-jrebel.sh
slightly because the existing startup.sh needs to be called within (instead of catalina.sh)
background information: the script is nothing more than adding the JRebel-Java-Agent (-javaagent:/path/to/jrebel.jar
) to the Tomcat (see http://manuals.zeroturnaround.com/jrebel/standalone/launch-quick-start.html)
seit Version 6 kann/sollte (???) noch eine Location für den sog. rebelbootCache angegeben werden:
mymodule
... by adding jrebel-maven-plugin
to mymodule/pom.xml
:
Afterwards you have to run mvn clean install
to generate the target/classes/rebel.xml
. It will look like this:
The rebel.xml
will also be part of the module artifact mymodule.jar
.
mymodule.jar
copy mymodule.jar to your Tomcat-deployment
start the Tomcat with startup-jrebel.sh
within the startup log you should see some JRebel Success messages
change MyClass.java
if the module mymodule
within your IDE
build the corresponding MyClass.class
by your IDE (in Eclipse usually done automatically - output folder is bin/classes
)
test your change in the running application
Here you can
restrict which modules are under Rebel-Control
usually I rebellize ALL modules and use rebel.packages
to select only some
configure license (rebel.license
)
configure logging (rebel.log
)
exclude/inlcude classes/packages
If you had such classes:
first.Alpha
first.foo.Bravo
second.Charlie
third.Delta
and you added -Drebel.packages=first.foo,second -Drebel.packages_exclude=first then JRebel would not reload Alpha and Bravo, because they're included in the exclude, and Delta, because it's not included in any of the rebel.packages. However it'd reload Charlie.
If you use this one you have to configure the JRebel-Java-Agent within your wrapper.conf
:
Every Artifact (jar, war, ear) under Rebel-Control needs a rebel.xml
that contains the back-reference to the code (which is under User-IDE-Control).
Usually your developers have different filesystem structures (maybe even different operating systems). Therefore the back-reference needs a user-specific part. I recommend to use a Java-System-Property (e. g. sourceFolder
) that is set within your application startup script (e. g. startup-jrebel.bat
) like this:
Within the user-unspecific and usually generated rebel.xml
you use the System-Property sourceFolder
in a way like this (see element rootPath
):
The relativePath
should reference to the folder reletive to this module ... this is hard to understand. Above configuration would fit for this filesystem structure
This will result in a generated rebel.xml
like this:
A JRebel application needs some more heap space ... otherwise you will have some performance issues because of garbage collector running continuously
JRebel is not restricted to web-applications. You can configure the JRebel-Java-Agent within any Java application.
Statement 1:
"JRebel is a JVM plugin (-javaagent) that integrates with the JVM and rewrites each class to be updateable. JRebel versions each class individually, instead of an entire application or module at a time – and it does not use classloaders. With JRebel, changes to classes are always visible with the Reflection API." (http://files.zeroturnaround.com/pdf/JRebelWhitePaper2014.pdf)
Statement 2:
"JRebel integrates directly with application servers and frameworks to propagate configuration changes from the changed classes and resources, and annotation changes are also visible via Reflection API. JRebel comes with special integrations for over 80 of the most popular frameworks and technologies (Spring, Hibernate, Seam, Wicket and Struts just to name a few)." (http://files.zeroturnaround.com/pdf/JRebelWhitePaper2014.pdf)
Statement 3:
"And for developers who run their application server on a virtual machine or other remote system, JRebel has a special feature called JRebel Remoting that eliminates the need to transfer the application manually. JRebel Remoting simply transfers the changed files only and then performs the reloading on remote server as expected." (http://files.zeroturnaround.com/pdf/JRebelWhitePaper2014.pdf)
JRebel not only supports hot-swapping for Java classes but also refactorings/extensions on framework-specific artifacts (spring application contexts, Hibernate mappings, Cxf, ...):
http://manuals.zeroturnaround.com/jrebel/misc/integrations.html
http://manuals.zeroturnaround.com/jrebel/remoting/index.html
JRebel not only supports IDE and application server running on the same machine. The IDE-JRebel-Plugin also supports remote deployments.
In this scenario the IDE-Plugin is responsible to transfer the changed artifacts to your deplyoment-machine. The application server on that deployment-machine is configured to have a back-reference to the transfer folder to reload updated resources.
Sorry, but I have never used it personally ...
the application is slightly slower than without JRebel ... but in developer environments this does not really matter.
application startup increases by 10-30% (but you will have to restart less often)
JSF-xhtml reload is in realtime
Java-Code changes are visible within 2-15 seconds
it takes only some minutes to make it running
it works without any requirements to your IDE ... therefore it works with EVERY IDE (you do not need the provided plugins).
even if you are a test-driven developer it makes sense to use JRebel
to identify the broken code - you often have an idea where the code is broken and use JRebel to check your assumption
to do rapid prototyping
Support is excellent (in 2014)
Well done, Zeroturnaround :-)
Have a look at the , video 1 and video 2
The needed rebel.xml
within each artifact (jar, war, ear) can be written manually or you can use the .
... are set within ~/.jrebel/jrebel.properties
()
You can see that in your rebellized deployed application there are some JRebel-Threads:
When you debug you can see that JRebel is there ... the Java-Classes are instrumented:
JRebel is really worth the money if a warm-restart approach () is not good enough.