Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

If you think Java development is already slow, just wait till you add a Java Web Framework

That's right, I'm slow. What of it?

That’s right, I’m slow. What of it?

In our last couple of blog posts in this series, ‘Why HotSwap wasn’t good enough in 2001… and still isn’t today’ and ‘My class loader hates me and wants to slow me down’, we’ve explored the problem that exists in Java around reloading classes and Java resources and we’ve seen why HotSwap doesn’t go far enough. But we haven’t yet talked about what happens when we build upon Java and use frameworks, such as Spring, Hibernate, JSF, Vaadin, Grails, etc.

There’s no point in saying the Java reload/redeploy problem is fixed just because we can reload Java classes; that’s just half the story. What if someone were to add a Spring bean, or annotation? What happens in the land of Spring to that bean? Do we need to restart/redeploy the application for these types of changes too?

Well, the answer is YES!!

Framework configurations typically have a “run once” style initialisation for both the framework itself as well as the components that use the framework. So if you were to need to make a code or configuration change, your application would need to be redeployed to make use of the new code and config and use any new initialisation values. That sucks, right? There’s no point in a tool, like JRebel, if it only works half the time. Let’s now look at how ZeroTurnaround, the creators of JRebel, approached this problem years ago in order to bring balance to the Java force.

Integrating with frameworks

Frameworks don’t typically have their own classloaders. This is left to the containers they run in, such as application server classloaders. This means there’s no customisation around the class loading that needs to be done by JRebel, instead it focuses on the configurations the framework uses.

The first part is initialisation of frameworks and components when configuration changes and this is easy; we simply call the framework initialisation methods which are made available to us as public APIs. We can call these as many times as we want, reinitialising existing apps and components… Oh no, wait, I was just dreaming, those APIs don’t actually exist in real life. Let’s see what the reality is.

First of all, every framework is different, and has different initialising methods, behaviour and nuances. One thing is common though, the initialisation code comes in two flavours: Code that must be ‘run once an only once’ and code that can be called multiple times without adding abnormalities to the environment. It’s our job to understand all parts of the framework initialisation and split them into two groups.

  1. Methods which entirely contain code that can be run over and over (performance willing) are great, as to reload configuration into an existing runtime, we simply make a call to that method and the magic happens.
  2. Methods which cannot be called again and again require additional workaround code to be added to ensure the right code is executed to refresh the runtime. We don’t try to act like like frameworks, so we don’t code an equivalent initialiser, instead we add byte code to existing framework code to protect code that should only be run once, and add code that works around these restrictions to give us the same result, leading to an up-to-date runtime when a developer makes changes to their applications.

This is quite messy to implement and achieve, and constantly needs updating when the frameworks change. Remember, these *aren’t* APIs, so they can pretty much change at any time! Also there are performance requirements which we put upon ourselves to ensure we only reinitialise the minimum necessary for you to see your framework changes appear in the runtime, so for a simple addition of a Spring bean, for example, we wouldn’t want to needlessly refresh all aspects of the Spring framework.

This leads us on to the next question… how do we know what has changed? How do we know what needs to be reinitialised? The answer lies in a plugin framework that ZeroTurnaround created as part of the JRebel SDK, which is used by JRebel and exposed for others to use for their frameworks or specific requirements. This plugin will monitor the reloading of resources, and execute any desired custom code in reaction. Basically you’ll use a JRebel integration plugin to say: “After this specific kind of a resource is updated, go through these specific initialisation steps to update my application’s state.”

A typical scenario would be the following: your application is using the Spring framework. You add a new bean in your springapplicationContext.xml and wire it to other existing beans in your runtime. Without an integration plugin explicitly telling Spring what to do, this changes will not be reflected in your application’s running state without a restart. But using an integration plugin, you could for example say: “Hey, if you see that I’ve changed something in applicationContext.xml, please be kind enough to perform a full reload and framework initialisation of all my beans!”.

Show me the code!

Let’s take a look at some issues that may arise. In this example, we’ll be looking at Spring Bean initialisation problems that may arise. Here we’re going to update a bean injection in our Spring descriptor from:

 <bean id="bean" class="springapp.bean.TestBean">
  <property name="value" value="Foo"/>


 <bean id="bean" class="springapp.bean.TestBean">
  <property name="value" value="Bar"/>

Our Spring plugin will listen for changes to this descriptor, and upon this change, we’ll need to rewire the bean. Not all beans will be reinitialized on this kind of change, and some for example singletons are not reinitialized. Lets look at the following code:

 <bean id="lazyBean" class="springapp.bean.LazyBean" lazy-init="true" />
 <bean id="prototypeBean" class="springapp.bean.PrototypeBean" singleton="false" />

Here we have a lazy initialisation and a sinlgleton prototype bean. Neither of these bean should be reinitialized once they have gone through initialisation, so in the following code, JRebel will never drive either of the exceptions thown, in the afterPropertiesSet initialisation methods.

public class PrototypeBean implements InitializingBean {
 public void afterPropertiesSet() {
  throw new RuntimeException("this bean should not be instantiated");

public class LazyBean implements InitializingBean {
 public void afterPropertiesSet() {
  throw new RuntimeException("this bean should not be instantiated");

Let’s look at an example of initialisation code on a Spring bean that shouldn’t be called twice. Consider the following code:

public class CustomUrlHandlerMapping implements InitializingBean {

  public SomeBean sb; 
  List<String> list= new ArrayList<List>();

  public void afterPropertiesSet() throws Exception {
    list.add(new BigObject());

Every time we reinitialise, we call afterPropertiesSet, because we presume that it needs to be called for any dependency changes, as SomeBean is Autowired. Every time this happens a new Object is added to an ArrayList and the current (maybe new) dependency is processed. But the consequences are as follows

  • There might be too many elements in the list (because of previous runs).
  • Whoever uses the list will spend more time on it because it is bigger.
  • Memory leaks because old object remains there.

Can we skip the afterPropertiesSet call? Well, not really because the newly autowired SomeBean needs to be processed. This is also common with EJB/JSF postConstruct methods.

More info on plugins in the JRebel SDK

A plugin is a JAR file that contains a class that implements the Plugin interface on the JRebel SDK. Give it a go yourself! We’ve written a tutorial that you can follow to create your own JRebel Plugin, so why not give it a go, and let me know how it works out in the comments below, or tweet @sjmaple.

This and all RebelLabs content is made possible because developers and enterprises love using ZeroTurnaround products (like JRebel) to make their coding experience more productive and enjoyable. If you dig free articles and other content, check out a free trial of JRebel and support the small-but-crafty RebelLabs team!



  • István Nagy

    I didn’t read the article fully yet, but maybe Spring Loaded would be useful for you :)

  • arhan

    Sure. It has been around for a long time and is used in a few fancy frameworks out there, like Ratpack and Grails.

  • Sorry but it only works for really simple and little projects. Java development is SLOW you can’t change rules fast and test it in a couple of seconds after. You have to follow the bureaucratic path of deploy it.
    Its not so simple, Spring is a bad sample, its one of the most bureaucratic and slow for develop new things frameworks ever created.
    I don’t buy your idea.

  • besides that, JRebel is paid.

  • arhan

    Well, a lot of great development tools are paid. Must be fair.

  • arhan

    “You have to follow the bureaucratic path of deploy it.” <<<< You are probably mixing up production deployment with development cycle.

  • Hi I work with JRebel because our projects doesn’t have any option, we receive some technologies already defined. JRebel ease things but it can do magic, there are some limitations intrinsic to application servers, complex environments, slow deployments, complex application server configurations… things like that and of course java itself is not so fast for development.
    we can’t for example get things done so fast as some people say on this article, its not realistic and doesn’t reflects the reality of the java ee developer.

  • arhan

    Of course, big projects are never fast. But I guess the point here is that Java can be considered for small projects too, right? :) So with frameworks like Spring Boot it doesn’t feel that kind of a monster any more.

  • The development and deploy or production environments are much of same, only differs each other by hardware resources… We all know that application servers aren’t different versions for one or another.
    That’s a real problem because you can’t easily runaway from it…

  • arhan

    Why would you follow a bureaucratic path to deploy while developing on your own machine? :)

    If deployment in your own machine takes ages then you’re kind of screwed yourself if you can’t or unwilling to make the things betted. Invent some dev mode for your app or the like.. or yeah, use JRebel.

    For instance, it is quite common to use embedded Jetty to run in development even if your production environment is all WebSphere.

  • You have a point here, in the ideal world things works like you said, but in my world its not possible having your own server for integration test. Unfortunately its not the reality of most companies were I’ve worked.

  • Pieter_H

    exactly – this sort of bureaucratic path / production deployment headaches are endemic to app servers, not frameworks. Spring Boot runs great on Cloud Foundry, and we’re doing some interesting work with JRebel there too… Cloud Foundry eliminates the production deployment bureaucracy and puts developers back in control.

  • Adam Koblentz

    Developers are awesome when they’re allowed to do what they need to. :D