On Habré, several articles were published where
JRebel was either just
mentioned , or information was posted that
a new version was released . At the same time, not all readers understood
what it was all about and
how this software works .
As a direct participant in the development of this product, I would like to clarify some points why JRebel exists and how it can help a Java developer.
Where do legs grow from?
')
The initial problem is known to almost any developer who works with Java: after any changes in the project, in order to see the result, quite a lot of time is spent on building and deploying in the container. On Habré excellent articles have already been published on how to
speed up or
automate the development process, I will not repeat. But the fact is that in the mentioned methods there are flaws: not all changes can be overloaded in the deployed application by regular means; it is very easy to get memory leaks that will lead to the need to restart the container. Technical details are well painted
in a series of articles in our website - I invite curious to read.
Where does the time go?
How does the development cycle of a web application look like in the classical form:
1. Made changes to the code (or resources)
2. Collected JAR / WAR / EAR
3. Deployed the archive in a container
4. Opened the deployed application, and, after some manipulations, saw the results of their work.
Depending on the size of the application, the container used, and some other factors, steps 2, 3 and 4 can take from a few seconds to completely irresponsible numbers. Our company conducted a
survey of developers regarding the technologies used and the time spent on application deployment. As it turned out, on average, it takes about 3 minutes at a time to deploy, and about 10 minutes per hour. In deplorable cases, where the deployment takes more than half an hour, it does not even make sense to ask a person how many times an hour he can repeat this process. The answer is obvious.
When the restart of the container / application takes a few seconds, the problem described above does not feel so much. However, as the project grows and becomes more complex, the inconvenience will be felt. And then you can think: maybe JRebel is what you need?
JRebel to help!
So, JRebel is a tool designed to get rid of the problem of redeploying an application during development, i.e. will save you a lot of time.
What advantages appear when using JRebel:
1. Since JRebel can load resources directly from the workspace, there is no need to collect the full application archive (JAR / WAR / EAR). It remains only to compile the modified code, which takes much less time than the complete build of the archive.
2. There is no redeployment of the application - again we save time.
3. New class loaders (classloaders) are not created, so there is less risk of memory leaks during updates. Accordingly, we save time on forced restarts of the container itself.
4. The state of objects and user session is saved. Therefore, ideally, you can stay on the same page, see the results of the changes - just press F5.
Installation and Setup
There are several installation options. Because Since most developers work using IDEs, such as Eclipse, NetBeans, or IntelliJ, the natural way to install is to install a plugin for an individual IDE.
Eclipse users can use the Eclipse Marketplace service to install. NetBeans and IntelliJIDEA users can find JRebel in the corresponding list of plugins. Detailed instructions can be found
here . After installing the plugin you will be told that it would be nice to register and get a license.

After
registration, JRebel is ready to use.
In fact, JRebel is not tied to a specific development environment, because it does not work in the IDE, but where the application is running - i.e. is bound to the JVM process with the
-javaagent argument, like this:
java -javaagent: /opt/jrebel/jrebel.jar -cp. my.awesome.ApplicationConfiguration
In most cases, JRebel does not require additional configuration, only the configuration file -
rebel.xml - which can be generated automatically using an IDE plugin.

The bottom line is that the agent (javaagent), which is JRebel, needs to know where the compiled classes are and static files (html, css, etc.). This will allow to download all the required resources not from the deployed archive, but directly from the project, where the programmer makes his changes.
If all projects would follow the “standard” directory structure, and would only be compiled using standard IDE tools, then perhaps the configuration file would not be needed - we could get all the information about the project from the IDE or work simply by convention. But since all developers have their own idea of standards, JRebel also needs some tips.
The configuration file itself has a fairly simple structure — you just need to specify the classpath and location of the static resources:
<?xml version="1.0" encoding="UTF-8"?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"> <classpath> <dir name="c:\myWorkspace\myWar\target\classes"/> <dir name="c:\myWorkspace\myWar\src\main\resources"/> </classpath> <web> <link target="/"> <dir name="c:\myWorkspace\myWar\src\main\webapp"/> </link> <link target="/jsps/"> <dir name="c:\myWorkspace\myWar\src\main\jsps"/> </link> </web> </application>
<?xml version="1.0" encoding="UTF-8"?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"> <classpath> <dir name="c:\myWorkspace\myWar\target\classes"/> <dir name="c:\myWorkspace\myWar\src\main\resources"/> </classpath> <web> <link target="/"> <dir name="c:\myWorkspace\myWar\src\main\webapp"/> </link> <link target="/jsps/"> <dir name="c:\myWorkspace\myWar\src\main\jsps"/> </link> </web> </application>
As you can see, with the help of such a file, it is possible to display any, the most non-standard project structure - in my experience, such requirements arise quite often. A detailed description of the options for rebel.xml can be found in the
documentation .
Important! In order for JRebel to read the configuration correctly, rebel.xml must be attached to the application to be deployed: for web applications, rebel.xml must appear in
WEB-INF / classes . For JAR files, rebel.xml should be in the root of the archive.

In the ideal case, only web.xml and rebel.xml can be in the archive, and the remaining resources can be displayed via paths in rebel.xml.
In the case of Maven projects, it is possible to use a
plugin that can generate a configuration file, and save it in the right place.
Launch
From IDE, the launch is fairly trivial. In the case of IntelliJIDEA, it is enough to use the new launch button, which appeared after installing the plugin:

In Eclipse, a new tab will be added to the launch configuration, where you can check whether JRebel is enabled for this launch, and some other options.

In case you want to run the container outside the development environment, then it is enough to add the correct path to jrebel.jar in the
-javaagent parameter in the scripts for the selected container. The
configuration guide provides a list of containers with examples of scripts to run for different JVM and OS.
Opportunities
In addition to displaying a project in an expanded application, which is simply a convenient automation tool, JRebel offers some more functionality. First of all, this is the main functionality - overloading changes in the code. Suppose in the course of work stumbled upon a method that here it’s like itching to refactor. Said and done, we call the extract method, which leads to the addition of a new method to the class. The standard code reloading tool, HotSwap, cannot handle this change. JRebel, in turn, will overload the class and write about it to the console. The overload will take place at the moment when the modified class will be used, thereby simulating the lazy behavior that is inherent in Java.
Further, suppose we use annotations for settings within a framework. For example, the value of
@RequestMapping
used to determine the path through which the controller will be available. By changing the value of the annotation, we expect to discover the resource in a new way in our application.
This will work as follows: after compilation, the annotation value will be available in the new version of the class. Annotations are not executable code, but some meta-data, depending on which the framework itself changes its behavior. Now that the new version of the class is loaded, you need to let the framework know that the metadata has changed and you should update your behavior. For such cases, JRebel requires special integration for each framework or container.
As with the annotations, special integration is required if the framework relies on the external configuration. For example, in the case of the Spring Framework, configurations can be specified both through annotations and through XML files.
For example, we added a new component (
bean ) to the XML configuration, and with the help of
@Autowired
annotations we want to transfer the newly created component to the controller.
Restrictions
As with all approaches described in Habré and JRebel there are some technical limitations.
At the time of this writing, changes to the class hierarchy are not supported, i.e. if in the program one class is already described as “A extends B”, then it cannot be changed to “A extends C”. The same applies to changing the list of interfaces - you cannot add or remove interfaces from a class declaration.
There are still some points to consider.
Static initialization JRebel tries to keep the state of objects that are already created in memory. Accordingly, there is no restart of constructors or a static initialization block. From this follows a couple of consequences.
By changing the value of the static field, we expect to see this new value in the new version of the class. The value is actually assigned to a static block that JRebel did not restart. Accordingly, we will not see the new value. At the moment, JRebel will restart the static block only if a new static field is added.
The reason for this behavior is that what happens in a static block can affect the state of an object in an undefined way, so JRebel tries to restart it only as a last resort.
The second consequence, which comes out of the fact that JRebel does not restart constructors, is that adding a new field to a class will be assigned a “default” value for this type. Those. if you add a field whose type is not a primitive, then the value assigned will be null, which in general can lead to a
NullPointerException if this field is dereferenced for an existing object.
JRebel SDK
As described above, special integration is required to support framework configurations in JRebel. We have already spent quite a lot of time and effort to implement all sorts of integration, and the
list of supported frameworks is quite impressive. When working with some frameworks, it happens that integration is not required and JRebel works with them quite well out of the box. We don’t need to go far for examples: without special integration for
Vaadin , JRebel works quite well with it, and our Finnish colleagues are very pleased that they can use JRebel with their own framework.
Unfortunately, there are not many such examples. Most of the frameworks still rely on the external configuration, which requires additional integration. We would be happy to realize the support of everyone and everything, but we cannot keep up with all the unknown frameworks, and in many firms we create our own “bikes”, the code of which we will never see. For such cases, JRebel has the opportunity to write your own integrations. We have a small
guide on our website about how you can implement JRebel support for your needs.
Resources
For those who are interested and want to learn more about the product, and how to use it, I can provide links to some resources.
The creator of JavaPassion maintains a
page where it collects and updates materials on using JRebel with different containers, frameworks and IDEs.
Quite often, we hold themed
webinars , which you can register for free and participate in - live to ask questions on a topic of interest.
There is
a JRebel channel on Vimeo, where you can find webinar recordings, as well as all kinds of demo recordings.
Total
I hope, after this article, to uninitiated readers it became clearer what JRebel is and how it can be used. If you have any questions, I will be glad to answer them in the comments.
For those who already use, and find some flaws in the behavior of this software, do not hesitate to write to us on the
forum or contact the technical support service, we will be very grateful.
Thanks for attention!