Documentation versions (currently viewingVaadin 24)

Hot Deploy & Live Reload

How to be able to live reload with JetBrains Runtime and HotswapAgent.

JetBrains Runtime offers hotswapping of any type of Java changes into a running JVM through the debug connection, typically established by the IDE to the running JVM. With other JDKs you have limited support for only some types of Java changes.

In addition to getting the Java changes into the running JVM, most frameworks have some global data that needs to be updated when a class changes, or some kind of caches that need to be cleared for the new class to take full effect. HotswapAgent is a collection of plugins for various frameworks, which offers these kinds of global updates and cache clearing when needed.

Setting up hotswapping consists of three steps:

  1. Install JetBrains Runtime

  2. Download HotswapAgent and install it into JetBrains Runtime

  3. Run the application using JetBrains Runtime with additional parameters

JetBrains Runtime

You can download the latest version from the JetBrains GitHub release page. Be sure to pick the correct architecture. You need to use JetBrains Runtime to execute your application, not necessarily your IDE.


You can download HotSwapAgent from the HotswapAgent GitHub release page. You need version 1.4.2 or later. Download the JAR file and place it inside the JetBrains Runtime installation directory as lib/hotswap/hotswap-agent.jar. You need to use that exact file name (you need to create the hotswap folder) for JetBrains Runtime to pick it up.

If you want to know more about the features of HotswapAgent, the documentation in the HotswapAgent webpage is a good resource.

Running the Application

To enable hotswapping, you need to pass -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar as JVM arguments (not program arguments) when launching the application.

If you have a Spring Boot application, you launch the application by running the main() method of your application class. After you have launched the application once, you’ll have a run configuration that you can edit in your IDE so that you can select the proper JDK and give the necessary parameters.

To do that in IntelliJ IDEA, select Run  Edit configurations…. With your application run configuration selected, you can select the JDK to use in the first drop-down. If JetBrains Runtime isn’t shown, you can select it through Select alternative JRE…. In the same dialog you need to click Modify options  Add VM options to be able to see the field where you can define the JVM arguments. Then you can add -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar.

If you have another type of application, you need to pass the JVM options in the appropriate way.

Verifying It Works

With the settings in place, when you start the application in debug mode, you’ll see the following type of log output:

HOTSWAP AGENT: 10:19:01.802 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {1.4.2-SNAPSHOT} - unlimited runtime class redefinition.
HOTSWAP AGENT: 10:19:02.065 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [JdkPlugin, ClassInitPlugin, AnonymousClassPatch, WatchResources, Hotswapper, Hibernate, Hibernate3JPA, Hibernate3, Spring, Jersey1, Jersey2, Jetty, Tomcat, ZK, Logback, Log4j2, MyFaces, Mojarra, Omnifaces, ELResolver, WildFlyELResolver, OsgiEquinox, Owb, OwbJakarta, Proxy, WebObjects, Weld, WeldJakarta, JBossModules, ResteasyRegistry, Deltaspike, GlassFish, Weblogic, Vaadin, Wicket, CxfJAXRS, FreeMarker, Undertow, MyBatis, IBatis, JacksonPlugin, Idea]

This indicates that HotswapAgent is loaded. Now, when you navigate to a view in your application, open the corresponding Java file in your project and make some changes (remember to compile and not only save the class if using IntelliJ IDEA), your view is reloaded in the browser and the changes are shown.

Remember to use "debug" mode
Don’t start the application in "run" mode. The debug connection to the JVM running the application is needed for hotswapping to work.
Don’t use mvn spring-boot:run
Don’t launch the Maven spring-boot:run target as that forks another JVM process. The debug connection is then established only to the Maven process and not the actual application, and hotswapping will not work.

Working Efficiently

By default, any change done in the Java code causes the application to reload in the browser. This is convenient when you make changes to the initial layout, constructors, post construct methods or similar. However, if you are changing the logic inside a listener there is no need to do a page reload for the change to have effect. You can then turn it off in the Vaadin Developer Tools on the Info tab. Especially when you edit code related to a dialog or some other part of the UI which isn’t directly mapped to a URL, it can be more efficient to disable live reload and manually reload the browser only when needed.

IntelliJ by default doesn’t compile a Java file when you save it. If you are used to pressing the compile shortcut then hotswapping works fine. Otherwise you might want to make IntelliJ automatically build the project when you save. You can do that through Settings  Build, Execution, Deployment  Compiler  Build project automatically. You also need to ensure that the build takes place when the application is running in debug mode, through Advanced Settings  Allow auto-make to start even if developed application is currently running. Finally, through Settings  Build, Execution, Deployment  Debugger  HotSwap, Reload classes after compilation should be set to Always.

Additional Considerations

You should disable other reloading or hot swapping solutions. For example, disable the automatic restart in the Jetty Maven plugin if you are using that. Omit or set <scanIntervalSeconds> to a value of 0 or less.

The live reload “quiet time” (milliseconds since last Java change before refreshing the browser) can be adjusted with the parameter vaadin.liveReloadQuietTime in the file. Increase this value if you notice the browser refreshing before modified Java files have been fully compiled. The default is 1,000 ms.

Changes to some parts of the Java code, such application startup listeners, don’t have any effect until the server is restarted and the startup listeners run again. For these you need to restart the server manually.

If you are using the @PreserveOnRefresh annotation, the same view instance is reused when the browser is reloaded. That means changes aren’t necessarily visible until the view is opened in another browser tab.