Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Quarkus 1.11 Introduces State Preserving Reload in Development Mode

Quarkus 1.11 Introduces State Preserving Reload in Development Mode

This item in japanese

Lire ce contenu en français

The beginning of the year brought a new ability to Quarkus’ development mode: state preserving reload. This was delivered in Quarkus 1.11+ and offers almost instantaneous reload times, preserving the previous state. Quarkus promises staggering reload and termination times and also improved efficiency while developing an application through Quarkus’ development mode, a hot redeploy mechanism through which code changes in an application will be recompiled and reloaded when refreshed in the browser. Designed for the age of the cloud, this can be used on remote containers as well, providing a remote development mode.

InfoQ reached out to Stuart Douglas, senior principal software engineer at Red Hat, for a deeper understanding of Quarkus’ development mode.

InfoQ: Thank you for taking the time to answer questions for our readers. What are your current responsibilities at Red Hat, that is, what do you do on a day-to-day basis?

Stuart Douglas:

I work on Quarkus full time, mostly on the core and HTTP layers. Day-to-day, it is pretty much the usual mix of fixing bugs and working on new features. I work from Australia, and I am the only one from the team in my timezone, which means any meetings involve really late nights.

InfoQ: The hot deploy feature in Quarkus’ development mode is very useful, especially with applications that require a lot of time to redeploy. How do developers enable this feature?


Development mode is part of the core of Quarkus, so every Quarkus application can use it. Running `mvn quarkus:dev` or `gradle quarkusDev` is enough to launch it. Every app that uses Quarkus should be able to use development mode. In addition, if you have a main class that you run from an IDE, it will just work in that environment as well. We even have support for it now in JBang.

InfoQ: What are your recommendations when using this feature? How does it cope with an instance of multiple code changes? Are there limits to its use?


The application is not reloaded until you refresh your browser, so if you have multiple changed files, it won’t attempt to compile and reload them until you refresh. The only real limitation is that you can’t live reload Quarkus extensions themselves, so if you have a project that also contains a Quarkus extension, part of your project won’t be reloadable (this is a bit of a corner case, in general we don’t recommend including an extension in a project).

InfoQ: Can you take us on an under-the-hood tour of how this feature was implemented?


There are a few parts to it. At launch, Quarkus discovers the local project structure, so it actually understands the layout of your project and where all the project files go. All the code that resides in the project is loaded into a disposable ClassLoader, while all libraries including Quarkus itself are loaded in a different ClassLoader.

When a HTTP request comes in to Quarkus (e.g. you hit refresh on your browser), we intercept this request very early on and scan all the source files to see if any have changed. If they have, we then recompile them, drop the disposable ClassLoader, restart Quarkus with a new ClassLoader and then let the original request continue to the updated version of the application. This means that you always see the most up-to-date version of the application. Refreshing your browser is the trigger we use to attempt the restart.

InfoQ: What was the biggest technical challenge while developing the hot deploy feature?


Getting it to work from the IDE was quite challenging. Quarkus is split into two parts, a runtime part that ends up in the final application and a deployment part that contains all the devmode functionality, as well as the code that generates the final application. In general, we only have the runtime part on the project’s classpath, so trying to bootstrap devmode without actually having the relevant classes on the classpath required some tricks.

InfoQ: As stated by Max Rydahl Andersen, distinguished engineer at Red Hat and creator of JBang, in his tweet, Quarkus 1.11+ adds a new ability to development mode to detect whether a change can be applied to JVM instrumentation. What are the benefits of this addition? Is it enabled by default?


There are two main benefits because you don’t have to restart the application; an instrumentation based restart is much faster (almost instant), so the only time spent on reloading is the time to compile the changes. The other benefit is that you can keep your application state, e.g. Hibernate, will not re-create the database which can save time.

It was enabled by default, however in Quarkus 1.13.1 we have changed this so it is off by default. What we have found is that it can cause some confusion if you have code that runs on startup (or only runs once when a Singleton is created). Because the application is not restarted, your changes don’t take effect immediately. For Quarkus 2.0, we will hopefully have a very simple way to toggle it on and off at runtime (probably via the Dev UI), so you will be able to pick which mode you want, and change it as needed with the push of a button.

InfoQ: Can you please share some details about the magic of how this new feature of development mode is implemented? Are there any known limitations that you are aware of?


When Quarkus boots in development mode, the Maven/Gradle plugins add a JavaAgent to the command line in order to get access to java.lang.instrument.Instrumentation which allows us to modify classes. After we have compiled the classes, we look at the new class and check to see if it has the exact same signature as the old version (e.g. no new methods, all annotations are the same, and basically check that the only thing that changed is the contents of the methods). If this check passes, we use the instrumentation API to replace the classes, rather than restarting Quarkus.

It’s only possible to use Instrumentation if the class’ signature has not changed.

InfoQ: What makes the hot deploy feature unique from similar tools, such as JRebel?


The main difference is that it is integrated into the project, so every developer can use it with no setup. Another big difference is that we take full control of the whole experience, including compilation, so we don’t rely on external tools. The HTTP-based approach to detect changes (instead of using a timer) means that developers can be sure they are always seeing the most up-to-date results.

By placing emphasis not only on fast reload of applications, but also on improved efficiency and feedback while developing them, Quarkus tries to bridge together the benefit of using a mature language, such as Java and its ecosystem, and the benefits of a quick feedback loop characteristic found mostly on scripting languages like Python and JavaScript.

Rate this Article