Upgrading from Vaadin 23
- Overview
- Limitations
- Preparation
- Jakarta EE 10 Namespaces
- Spring Upgrade Instructions
- Java Version
- Application Servers
- Frontend Sources Directory
- Unification with Hilla & Integration with React
- Polymer Templates
- Multiplatform Runtime
- Maven & Gradle Plugins
- SLF4J 2.0
- Line-Awesome Icons Set Library
- New Types Definition
- Breaking Changes in Vaadin Components
- Field Validation Changes
- Removed Deprecations
This guide goes through the changes you’ll need to make in your applications when upgrading from Vaadin 23 to the latest version. After making them, your application should compile, run, behave, and look the way it did before you upgraded.
Tip
|
Upgrading from Earlier Version
See Vaadin 14 to 23 Upgrade Instructions if you’re upgrading from a version earlier than Vaadin 23.
|
Many of the breaking changes are needed because of fundamental changes in the Java platform and the major dependencies on which Vaadin relies. This includes the following:
- Servlet 6
-
Vaadin 24 is based on Servlet 6 specifications. It’s compatible with Jakarta EE 10. Vaadin encapsulates the usage of the classes from
javax
andjakarta
packages. Therefore, application code doesn’t need to use servlets, directly. Nevertheless, this is still needed in various cases — like accessing cookies, setting servlet parameters, etc. - Spring Boot 3
-
Vaadin 24 uses the latest Spring Boot 3 and Spring Framework 6 versions. This leads to making breaking changes in Spring-based features, compared to earlier Spring Boot 2 and Spring Framework 5 versions.
- Java 17
-
Vaadin 24 requires Java 17 or later. This is dictated by Spring Framework and newer versions of application servers.
Overview
Vaadin 24 doesn’t change fundamentally how applications are developed and behave. Nevertheless, the upgrade process requires the following essential tasks and tests:
- Preparation
-
Upgrade the Vaadin version in the project’s
pom.xml
file, checking for the latest Vaadin 24 release in GitHub. - Jakarta EE 10
-
Convert package names to Jakarta EE 10 namespace.
- Upgrade Spring
-
For Spring-based applications, upgrade to Spring Boot 3 or Spring Framework 6, depending on which is used in your project. For non-Spring applications, upgrade the application server version to one that’s compatible with Jakarta EE 10.
- Other Dependencies
-
Upgrade third-party dependencies used in your project (e.g., Maven/Gradle plugins, libraries, frameworks) to the Jakarta and Spring-compatible versions.
- Verify & Test
-
Ensure your application is not using deprecated code fragments.
Make sure your application runs well on Java 17 runtime.
Verify that the frontend build works as it should with Vite since webpack is no longer supported.
Limitations
Portlet and OSGi integrations are not included for two reasons: First, the latest Portlet 3 specification corresponds to Servlet 3, and it doesn’t work with Servlet 6. Second, a Jakarta EE 10 compatible version of OSGi core runtime Apache Felix 8 is under development. The Apache Karaf container is based on Apache Felix and doesn’t have a Jakarta-compatible version.
Preparation
Upgrade the Vaadin version in the pom.xml
and gradle.properties
files to the latest release like so:
<vaadin.version>24.6.2</vaadin.version>
See the list of releases on GitHub for the latest one.
Jakarta EE 10 Namespaces
You can use the free tools, Eclipse Transformer and Apache migration tool for the package name conversion.
When applied to a project, they’ll convert Java class imports, manifests, property files, and other resources to use jakarta.*
namespace when needed. Conversion instructions are in each tool’s README
file.
The last versions of IntelliJ IDEA offer migration refactoring tools, including a Java EE to Jakarta EE package converter. Make sure that the Jakarta specifications in your project have the correct versions. Refer to the full list of Jakarta EE 10 specifications for more information.
Below are a few examples:
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.enterprise.concurrent</groupId>
<artifactId>jakarta.enterprise.concurrent-api</artifactId>
<version>3.0.0</version>
</dependency>
Spring Upgrade Instructions
Spring Boot 3 and Spring Framework 6 don’t fundamentally change how applications are developed. The main changes are regarding Jakarta EE 10 namespaces and supported products, the Java version, and the dependency upgrades and deprecations.
Spring Boot 3 and Framework 6 use new versions of third-party dependencies: Hibernate 6, Hibernate Validator 8, servlet containers (e.g., Jetty 11, Tomcat 10.1), and many others. Spring has available the Dedicated Migration Guide for Spring-boot 3.0 and the Upgrading to Spring Framework 6.x Guide. You may want to consult them.
To browse a full list of changes, see the Spring-boot 3.0 Release Notes and the What’s New in Spring Framework 6.x page.
The following sections provide a general overview of the changes needed for Spring-based Vaadin applications.
Upgrade Spring to Latest
You’ll need to upgrade Spring to the latest versions, including the starter parent dependency:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
</parent>
Deprecation
The deprecated VaadinWebSecurityConfigurerAdapter
class was removed since Spring no longer includes the WebSecurityConfigurerAdapter
class. Use instead the VaadinWebSecurity
base class for your security configuration. Below is an example of this:
@EnableWebSecurity
@Configuration
public class SecurityConfig extends VaadinWebSecurity {
@Override
public void configure(HttpSecurity http) throws Exception {
/**
* Delegating the responsibility of general configuration
* of HTTP security to the superclass.
*
* It's configuring the following:
* - Vaadin's CSRF protection by ignoring internal framework requests,
* - default request cache,
* - ignoring public views annotated with @AnonymousAllowed,
* - restricting access to other views/endpoints, and
* - enabling ViewAccessChecker authorization.
*/
// You can add any possible extra configurations of your own
// here - the following is just an example:
http.rememberMe().alwaysRemember(false);
// Configure your static resources with public access before calling
// super.configure(HttpSecurity) as it adds final anyRequest matcher
http.authorizeHttpRequests(auth -> {
auth.requestMatchers(new AntPathRequestMatcher("/admin-only/**"))
.hasAnyRole("admin")
.requestMatchers(new AntPathRequestMatcher("/public/**"))
.permitAll();
});
super.configure(http);
// This is important to register your login view to the
// view access checker mechanism:
setLoginView(http, LoginView.class);
}
@Override
public void configure(WebSecurity web) throws Exception {
// Customize your WebSecurity configuration.
super.configure(web);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* Demo UserDetailsManager which only provides two hardcoded
* in-memory users and their roles.
* This shouldn't be used in real-world applications.
*/
@Bean
public UserDetailsService userDetailsService(
PasswordEncoder passwordEncoder) {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user")
.password(passwordEncoder.encode("userPass"))
.roles("USER").build());
manager.createUser(User.withUsername("admin")
.password(passwordEncoder.encode("adminPass"))
.roles("USER", "ADMIN").build());
return manager;
}
}
In the example here, AuthenticationManagerBuilder
— used in Spring Boot 2 — is replaced by UserDetailsService
. Also, http.authorizeRequests().antMatchers()
is replaced with http.authorizeHttpRequests(auth → auth.requestMatchers())
.
Spring Security
If the application is using Spring Security 5, the default behavior is for the SecurityContext
to be saved automatically to the SecurityContextRepository
using the SecurityContextPersistenceFilter
.
In Spring Security 6, users now must explicitly save the SecurityContext
to the SecurityContextRepository
.
You can return the old behavior by adding to configuration(HttpSecurity)
the line http.securityContextsecurityContext) → securityContext.requireExplicitSave(false;
.
For more information see Servlet Migrations - Session Management.
Java Version
Java 17 or later is required. Below is an example of how to use this version:
<properties>
<java.version>17</java.version>
<!-- OR: -->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
Application Servers
Before migrating, find the corresponding version of the Jakarta EE 10-compatible application server used in your project. See Jakarta Compatible Products for more information.
CDI 4.0 specification — which is part of Jakarta EE 10 — changes the default value of the bean-discovery-mode
attribute to annotated
and uses annotated
as the default when an empty beans.xml
file is found in a deployment. See Jakarta CDI page for more information.
To let the container scan and manage Vaadin components and views when the bean-discovery-mode
attribute is not defined and the default is used, you should annotate Vaadin components and views with the com.vaadin.cdi.annotation.CdiComponent
to allow them to be detected correctly as CDI beans.
As an alternative, you can set bean-discovery-mode=all
in the beans.xml
file if it’s applicable to your project. However, this isn’t recommended.
Frontend Sources Directory
Vaadin uses the {project directory}/src/main/frontend/
directory as the default location for frontend sources. The legacy location {project directory}/frontend/
is still supported and used if the {project directory}/src/main/frontend/
directory doesn’t exist.
Although it’s currently optional, if you’re using the legacy location, you should move your files to a new location, as support for this may be removed in the future releases.
Unification with Hilla & Integration with React
Vaadin 24.4 and later versions unify the server and client development approaches known as Vaadin Flow and Hilla, respectively. This makes it easier to create hybrid applications, including:
-
unify dependencies for the Vaadin, making the project configuration simpler;
-
develop React-based routes and components in Vaadin Flow applications;
-
export Flow components or entire views into frontend views implemented with React; and
-
use unified routing based on React Router.
Hilla & React Dependencies
Vaadin 24 includes React dependencies, such as React, React Router, and Vaadin React-based components provided by Vaadin. These dependencies allow you to start developing immediately with React.
Vaadin React includes free, core components and commercial (i.e., professional) components. These components are shipped in the separate npm packages: @vaadin/react-components
, which is only free; and @vaadin/react-components-pro
, which is only commercial. Vaadin adds both of these packages to package.json
if the com.vaadin:vaadin
artifact is in the project’s configuration:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin</artifactId>
</dependency>
It adds only @vaadin/react-components
if com.vaadin:vaadin-core
is used:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-core</artifactId>
</dependency>
Vaadin Flow applications don’t need any changes regarding React or Hilla dependencies management. However, the opt-out options are available for the following cases:
-
Lit is used for frontend development instead of React;
-
having Hilla or React dependencies is undesirable; and
-
you need the legacy
vaadin-router
(e.g. if your project uses an add-on that needs it).
Opting-Out of React
To opt-out, change both reactEnable
plugin configuration parameter and vaadin.react.enable
configuration property to false
.
Maven plugin configuration parameter in the vaadin-maven-plugin
:
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<configuration>
<reactEnable>false</reactEnable>
</configuration>
</plugin>
Below is the configuration property with Spring Boot application properties:
vaadin.react.enable=false
Disabling it excludes React completely from your project and fallbacks to vaadin-router
and Lit.
Two Places for Same Property
Two properties exists mainly to support the development and production modes. reactEnable
is effective for both; vaadin.react.enable
, though, is effective only for development.
Production package and bundle is built by running the Vaadin Maven and Gradle plugin with build-frontend
goal. The reactEnable
plugin configuration parameter value is contained in the build information file inside the package, which is used as a default value in runtime.
Configuration property vaadin.react.enable
overrides the default value in the production package at runtime. However, it doesn’t change the production bundle content.
Running an application with the vaadin.react.enable
in production mode means possibly using a different value than what was used when the production package was built. Both properties should have the same value to avoid confusion as to which is effective.
Opting-Out of React with Spring
System property has priority over application property. When running a Spring application with Maven, you may need to wrap system property in -Dspring-boot.run.jvmArguments=vaadin.react.enable=false"
.
Simplified Maintenance
To make it easier to keep both properties the same, Spring supports Automatic Property Expansion with Maven and with Gradle. Please follow the instructions in the Spring documentation to enable this feature.
When running with Maven and using spring-boot-starter-parent
, property value can have @reactEnable@
, which is replaced with the value of the reactEnable
Maven project property. Otherwise, please follow the Spring documentation to see how to enable resources
filtering and set maven-resources-plugin
configurations.
vaadin.react.enable=@reactEnable@
<properties>
<reactEnable>false</reactEnable>
</properties>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<configuration>
<reactEnable>${reactEnable}</reactEnable>
</configuration>
</plugin>
Opting-Out of React without Spring
When Spring is not used, set vaadin.react.enable
system property or react.enable
initialization parameter.
Opting-Out of React Components
If you don’t need Vaadin’s React components, you can opt-out by excluding the flow-react
package in your dependencies. This replaces the @vaadin/react-components
and @vaadin/react-components-pro
packages in your package.json
with @vaadin/*
web components:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin</artifactId>
<exclusions>
<exclusion>
<groupId>com.vaadin</groupId>
<artifactId>flow-react</artifactId>
</exclusion>
</exclusions>
</dependency>
This example exclude Hilla from a project when using Maven:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin</artifactId>
<exclusions>
<exclusion>
<groupId>com.vaadin</groupId>
<artifactId>hilla</artifactId>
</exclusion>
<exclusion>
<groupId>com.vaadin</groupId>
<artifactId>hilla-dev</artifactId>
</exclusion>
</exclusions>
</dependency>
This example is for when you’re using Gradle:
buildscript {
configurations.classpath {
exclude group: 'com.vaadin', module: 'hilla-engine-core'
}
}
dependencies {
implementation ("com.vaadin:vaadin") {
exclude group: 'com.vaadin', module: 'hilla-dev'
}
}
hilla.active=false
The following Hilla dependencies are included in Vaadin. You don’t need to include these explicitly:
-
dev.hilla:hilla-bom
-
dev.hilla:hilla-react
-
dev.hilla:hilla
Frontend Bundles & Hot Deploy Modes
Vaadin chooses using a pre-compiled frontend bundle, or re-building a new bundle, or starting a frontend development server. If it detects Hilla views in a project, it uses development server — unless you set the configuration parameter, vaadin.frontend.hotdeploy=false
. Conversely, for Flow applications it uses frontend bundle — unless you set the configuration parameter, vaadin.frontend.hotdeploy=true
.
Default Location for Client-Side Views
Place your React client-side views in the src/main/frontend/views/
directory. Vaadin searches for any .tsx
or .jsx
React views. It registers them as React routes if they’re present in this directory or subdirectories. See Routing for more details about File-Based Routing.
Polymer Templates
Polymer support has been deprecated since Vaadin 18 was released in November 2020, in favor of faster and simpler Lit templates. The built-in support for Polymer templates has been removed and is only available for Prime and Ultimate customers via an addon. However, a free conversion tool is also available to assist you in converting your Polymer templates to Lit.
Commercial Polymer Template Addon
If you have a Prime or Ultimate subscription, you can continue to use Polymer templates by adding the following dependency to your pom.xml
file:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-polymer-template</artifactId>
</dependency>
Then you’ll need to update all imports of the PolymerTemplate
classes to the new coordinates: com.vaadin.flow.component.polymertemplate.PolymerTemplate
.
Polymer to Lit Conversion Tool
You can use the free conversion tool to facilitate the migration from Polymer to Lit by converting automatically basic Polymer constructions into their Lit equivalents in Java and JavaScript source files.
Limitations
The converter covers only basic cases. More advanced cases, such as TypeScript source files or usage of internal Polymer API, should still be converted manually.
See the Polymer-to-Lit converter documentation for more information about limitations and supported transformations.