Skip to content

Commit 92f298d

Browse files
committed
Supplement with more breaking change from release notes
1 parent c303e39 commit 92f298d

File tree

1 file changed

+186
-89
lines changed

1 file changed

+186
-89
lines changed

articles/upgrading/index.adoc

Lines changed: 186 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Java 21::
2121
Vaadin 25 requires Java 21 or later. Java 21 is the latest LTS version of Java. Upgrading to Java 21 might require you to upgrade other dependencies in your application.
2222

2323
Spring Boot 4::
24-
Vaadin 25 uses the latest Spring Boot 4 and Spring Framework 7 versions. This leads to making breaking changes in Spring-based features, compared to earlier Spring Boot 3.5 and Spring Framework 6 versions.
24+
Vaadin 25 uses the latest Spring Boot 4 and Spring Framework 7 versions. This leads to making breaking changes in Spring-based features, compared to earlier Spring Boot 3.5 and Spring Framework 6 versions. Details can be found in link:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide[Spring Boot 4 Migration Guide].
2525

2626
Servlet 6.1::
2727
Vaadin 25 is based on link:https://jakarta.ee/specifications/servlet/6.1/[Servlet 6.1] specification, which is compatible with link:https://jakarta.ee/specifications/platform/11/[Jakarta EE 11]. When upgrading from Vaadin 24 (Servlet 6 and Jakarta EE10), changes are typically not needed.
@@ -30,7 +30,13 @@ Gradle 8/9::
3030
Gradle 8 (8.14 and later) and Gradle 9 releases are supported.
3131

3232
Jackson 3::
33-
Elemental has been replaced with Jackson while Jackson version has been updated to 3. This only affects you if the your application uses some of the affected low-level APIs. Details can be found in link:https://github.com/vaadin/flow/issues/21060[Finalize Jackson conversion] and its sub-issues.
33+
Elemental has been replaced with Jackson while Jackson version has been updated to 3. This only affects you if your application uses some of the affected low-level APIs. Details can be found in link:https://github.com/vaadin/flow/issues/21060[Finalize Jackson conversion] and its sub-issues.
34+
35+
Node.js 24::
36+
Vaadin 25 requires Node.js 24 or later for building the frontend part of the application. Node.js 24 becomes the active LTS before Vaadin 25.0.0 - guaranteeing the longest possible support.
37+
38+
React 19::
39+
Vaadin 25 uses React 19 for the React-based components and views. Details about the changes in React 19 can be found in link:https://react.dev/blog/2024/04/25/react-19-upgrade-guide[React 19 Upgrade Guide].
3440

3541

3642
== Overview
@@ -55,11 +61,6 @@ Ensure your application is not using deprecated code fragments.
5561
Make sure your application runs well on Java 21 runtime.
5662

5763

58-
== Limitations
59-
60-
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.1. Second, a Jakarta EE 10 compatible version of OSGi core runtime https://felix.apache.org/documentation/index.html[Apache Felix 8] is under development. The https://karaf.apache.org/[Apache Karaf] container is based on Apache Felix and doesn't have a Jakarta-compatible version.
61-
62-
6364
== Preparation
6465

6566
Upgrade the Vaadin version in the [filename]`pom.xml` and [filename]`gradle.properties` files to the latest release like so:
@@ -85,11 +86,10 @@ See the link:https://github.com/vaadin/platform/releases[list of releases on Git
8586

8687
== Spring Upgrade Instructions
8788

88-
To browse a full list of changes, see the https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0.0-M3-Release-Notes[Spring-boot 4.0 Release Notes] and the https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-7.0-Release-Notes[What's New in Spring Framework 7.x] page.
89+
To browse a full list of changes, see the link:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0.0-M3-Release-Notes[Spring-boot 4.0 Release Notes] and the https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-7.0-Release-Notes[What's New in Spring Framework 7.x] page.
8990

9091
The following sections provide a general overview of the changes needed for Spring-based Vaadin applications.
9192

92-
9393
=== Upgrade Spring to Latest
9494

9595
You'll need to upgrade Spring to the latest versions, including the starter parent dependency:
@@ -105,16 +105,13 @@ You'll need to upgrade Spring to the latest versions, including the starter pare
105105
----
106106

107107

108-
=== Deprecation
108+
=== Security Configuration Changes
109109

110-
The deprecated `VaadinWebSecurity` class was removed. Use instead the `VaadinSecurityConfigurer` class for your security configuration. Below is an example of this:
111-
112-
[.example]
113-
--
110+
The deprecated [classname]`VaadinWebSecurity` class has been removed from Vaadin 25. Use instead the [classname]`VaadinSecurityConfigurer` base class for your security configuration. Below is an example of this:
114111

115112
[source,java]
116113
----
117-
<source-info group="VaadinSecurityConfigurer"></source-info>
114+
<source-info group="VaadinWebSecurity (deprecated since V24.9)"></source-info>
118115
@EnableWebSecurity
119116
@Configuration
120117
@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class)
@@ -179,73 +176,157 @@ public class SecurityConfig {
179176
}
180177
----
181178

179+
==== Upgrade To VaadinSecurityConfigurer From VaadinWebSecurity
180+
181+
. Add a new method to the security configuration class to provide the security filter chain bean
182+
183+
+
182184
[source,java]
183185
----
184-
<source-info group="VaadinWebSecurity (deprecated since V24.9)"></source-info>
185-
@EnableWebSecurity
186-
@Configuration
187-
@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class)
188-
public class SecurityConfig {
186+
@Bean
187+
public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception {
188+
return http.with(VaadinSecurityConfigurer.vaadin(), vaadin -> {
189+
...
190+
}).build();
191+
}
192+
----
193+
+
189194

190-
@Bean
191-
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
192-
/**
193-
* Delegating the responsibility of general configuration
194-
* of HTTP security to the VaadinSecurityConfigurer.
195-
*
196-
* It's configuring the following:
197-
* - Vaadin's CSRF protection by ignoring internal framework requests,
198-
* - default request cache,
199-
* - ignoring public views annotated with @AnonymousAllowed,
200-
* - restricting access to other views/endpoints, and
201-
* - enabling ViewAccessChecker authorization.
202-
*/
195+
**Hint**: you can use a static import for `VaadinSecurityConfigurer.vaadin()`.
203196

204-
// You can add any possible extra configurations of your own
205-
// here - the following is just an example:
206-
http.rememberMe(customizer -> customizer.alwaysRemember(false));
197+
. Move and adapt the code of the `configure(HttpSecurity)` method into `vaadinSecurityFilterChain()`.
198+
.. customizations of [classname]`HttpSecurity` placed before `super.configure()` can be moved before the `with(vaadin(), vaadin -> {})` instruction.
199+
.. calls to [classname]`VaadinWebSecurity` methods have related methods in the [classname]`VaadinSecurityConfigurer`.
207200

208-
// Configure your static resources with public access before calling
209-
// VaadinSecurityConfigurer.vaadin() as it adds final anyRequest matcher
210-
http.authorizeHttpRequests(auth -> {
211-
auth.requestMatchers("/admin-only/**").hasAnyRole("admin")
212-
.requestMatchers("/public/**").permitAll();
213-
});
201+
+
202+
--
203+
.Before
204+
[source,java]
205+
----
206+
@Override
207+
protected void configure(HttpSecurity http) throws Exception {
208+
http.authorizeHttpRequests(registry -> {
209+
registry.requestMatchers("/assets/**").permitAll();
210+
});
211+
super.configure(http);
212+
setLoginView(http, "/login", "/");
213+
}
214+
----
214215

215-
http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
216-
// This is important to register your login view to the
217-
// view access checker mechanism:
218-
configurer.loginView(LoginView.class);
219-
});
220216

221-
return http.build();
222-
}
217+
.After
218+
[source,java]
219+
----
220+
@Bean
221+
public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception {
222+
http.authorizeHttpRequests(registry -> {
223+
registry.requestMatchers("/assets/**").permitAll();
224+
});
225+
http.with(vaadin(), vaadin -> vaadin.loginView("/login", "/"));
226+
return http.build();
227+
}
228+
----
229+
--
223230

224-
@Bean
225-
public PasswordEncoder passwordEncoder() {
226-
return new BCryptPasswordEncoder();
227-
}
231+
. If `configure(WebSecurity web)` is overridden you might:
228232

229-
/**
230-
* Demo UserDetailsManager which only provides two hardcoded
231-
* in-memory users and their roles.
232-
* This shouldn't be used in real-world applications.
233-
*/
234-
@Bean
235-
public UserDetailsService userDetailsService(
236-
PasswordEncoder passwordEncoder) {
237-
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
238-
manager.createUser(User.withUsername("user")
239-
.password(passwordEncoder.encode("userPass"))
240-
.roles("USER").build());
241-
manager.createUser(User.withUsername("admin")
242-
.password(passwordEncoder.encode("adminPass"))
243-
.roles("USER", "ADMIN").build());
244-
return manager;
245-
}
233+
.. Move the rules in the security filter chain bean definition using `HttpSecurity.authorizeRequests()` and remove the original method (recommended by Spring, to prevent skipping all other filters in the chain):
234+
235+
+
236+
--
237+
.Before
238+
[source,java]
239+
----
240+
@Override
241+
protected void configure(WebSecurity web) throws Exception {
242+
web.ignoring().requestMatchers("/images/**");
243+
}
244+
----
245+
246+
.After
247+
[source,java]
248+
----
249+
@Bean
250+
public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception {
251+
http.authorizeHttpRequests(registry -> {
252+
registry.requestMatchers("/assets/**", "/images/**").permitAll();
253+
});
254+
http.with(vaadin(), vaadin -> vaadin.loginView("/login", "/"));
255+
return http.build();
246256
}
247257
----
258+
--
248259

260+
.. OR, expose a [classname]`WebSecurityCustomizer` bean by your own and remove the original method
261+
262+
+
263+
--
264+
.Before
265+
[source,java]
266+
----
267+
@Override
268+
protected void configure(WebSecurity web) throws Exception {
269+
web.ignoring().requestMatchers("/images/**");
270+
}
271+
----
272+
273+
.After
274+
[source,java]
275+
----
276+
@Bean
277+
public WebSecurityCustomizer webSecurityCustomizer() {
278+
return (web) -> web.ignoring().requestMatchers("/images/**");
279+
}
280+
----
281+
--
282+
283+
. If stateless authentication is configured (`setStatelessAuthentication(...)`), replace the call using `VaadinStatelessSecurityConfigurer`
284+
285+
+
286+
--
287+
.Before
288+
[source,java]
289+
----
290+
@Override
291+
protected void configure(HttpSecurity web) throws Exception {
292+
//...
293+
setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256), "com.example.application");
294+
//...
295+
}
296+
----
297+
298+
.After
299+
[source,java]
300+
----
301+
@Bean
302+
public SecurityFilterChain vaadinSecurityFilterChain(HttpSecurity http) throws Exception {
303+
//...
304+
http.with(new VaadinStatelessSecurityConfigurer<>(), stateless -> stateless.issuer("com.example.application")
305+
.withSecretKey()
306+
.secretKey(new SecretKeySpec(Base64.getDecoder().decode(authSecret), JwsAlgorithms.HS256))
307+
);
308+
//...
309+
}
310+
----
311+
--
312+
313+
. Remove `extends VaadinWebSecurity` and import the Vaadin security context holder strategy
314+
315+
[source,java]
316+
----
317+
@EnableWebSecurity // should be already present
318+
@Configuration // should be already present
319+
@Import(VaadinAwareSecurityContextHolderStrategyConfiguration.class)
320+
public class SecurityConfiguration {
321+
}
322+
----
323+
324+
325+
==== Restrict Access By Default For Url-Based Security
326+
URLs not explicitly specified in security configuration changed from being allowed for authenticated users to restricted by default. This requires extra security rules (path matchers) for URLs that were allowed only for authentication users.
327+
328+
==== Deny Access Ff Flow Layout Has No Security Annotation
329+
Vaadin Flow layouts now require access annotation (e.g. [classname]`RolesAllowed`) on layout classes. This was added to align with auto-layout default security rules.
249330

250331
== Java Version
251332

@@ -291,28 +372,16 @@ java {
291372
----
292373
--
293374

294-
295375
== Application Servers
296376

297377
Before migrating, find the corresponding version of the Jakarta EE 11-compatible application server used in your project. See link:https://jakarta.ee/compatibility/[Jakarta Compatible Products] for more information.
298378

299-
300-
301-
[role="since:com.vaadin:[email protected]"]
302-
== Frontend Sources Directory
303-
Vaadin uses the [filename]`{project directory}/src/main/frontend/` directory as the default location for frontend sources. Legacy location [filename]`{project directory}/frontend/` is no longer supported or used automatically [filename]`{project directory}/src/main/frontend/` directory doesn't exist, a warning will be output instead. If you're using the legacy location, you should move your files to the new location, or add the `frontendDirectory` parameter and point it to the legacy location for it to function correctly.
304-
305-
306-
== Polymer Support
307-
308-
In Vaadin 25, the `@polymer/polymer` dependency in default `package.json` is removed by default, if polymer-template module is not found from the project. If the application uses Polymer in add-ons may require to add `@NpmPackage(value = "@polymer/polymer", version = "3.5.2")` or add an import to `package.json` explicitly. Details can be found in link:https://github.com/vaadin/flow/issues/21421[Ensure Flow works without Polymer in v25]
309-
310-
311379
== Maven & Gradle Plugins
312380

313-
Ensure that the Maven plugins which are explicitly defined in your project, are compatible with Java 21. <TODO: any specific versions to mention?>
381+
Ensure that the Maven plugins which are explicitly defined in your project, are compatible with Java 21.
382+
A safe choice: Maven 3.9.11 (or the latest in the 3.9 line) or Maven 4.0.x (once stable) if you are comfortable with that.
314383

315-
To run Gradle on top of Java 21 and latest Spring Boot 4 versions, you'll need to use version 8.14 or later. See the https://docs.gradle.org/8.14/release-notes.html[Gradle release notes] for further details. If your project uses Spring Boot, upgrade the plugin `org.springframework.boot` to version 4.0.0.
384+
To run Gradle on top of Java 21 and latest Spring Boot 4 versions, you'll need to use version 8.14 or later. See the link:https://docs.gradle.org/8.14/release-notes.html[Gradle release notes] for further details. If your project uses Spring Boot, upgrade the plugin `org.springframework.boot` to version 4.0.0.
316385

317386
If you're using a Gradle wrapper, update it to version 8.14 by executing the following from the command line:
318387

@@ -323,17 +392,45 @@ If you're using a Gradle wrapper, update it to version 8.14 by executing the fol
323392

324393
For Java 21 compatibility, you may need to update the `sourceCompatibility` setting in your project's build file to version 21. Check your project's build file and make any necessary changes.
325394

395+
== TestBench
396+
397+
[classname]`ComponentTester` in UI Unit test has been updated to prove a common [methodname]`void click()` method. However, the new method clashes with a similar existing method in [classname]`AnchorTester` and [classname]`RouterLinkTester` that returns an [classname]`HasElement` instance as a result of the navigation. Existing tests that rely on the return type have to migrate to the new [methodname]`navigate()` method; if the return value is not used, there is no need for changes.
398+
399+
Because of the change, the [classname]`com.vaadin.flow.component.html.testbench.ClickHandler` class has been removed. The interface, meant to be used with [classname]`ComponentTester` subclasses, should not be needed anymore. In this case, [classname]`com.vaadin.testbench.unit.Clickable` is a valid substitute.
400+
326401
== Quarkus
327402

328403
Vaadin Quarkus extension is changed to build production package by default. No need for production profile with exclusions for development tools in Maven configurations because Vaadin Quarkus extension has build-in Vaadin plugin handling production packaging.
329404

330-
To allow project to keep build configuration unchanged, Vaadin Quarkus extension has `vaadin.build.enabled` property to change the default behaviour. Disable Vaadin plugin by adding `vaadin.build.enabled=false` in `application.properties` file to keep using profile based configuration.
405+
To allow project to keep build configuration unchanged, Vaadin Quarkus extension has `vaadin.build.enabled` property to change the default behavior. Disable Vaadin plugin by adding `vaadin.build.enabled=false` in `application.properties` file to keep using profile based configuration.
331406

332-
== Removed Deprecations
407+
== Binder
408+
[methodname]`Binder.validate()` implementation has been changed to behave as its javadoc states. In other words, [methodname]`Binder.validate()` no longer fails when bean level validators have been configured but no bean is currently set (i.e. [classname]`Binder` is used in buffered mode).
409+
410+
== Server-Side Modality
411+
[classname]`Dialog` has become less strict and allows background requests to server. Vaadin Flow allows to change this behavior if needed through [methodname]`Dialog.setModality(ModalityMode)` method.
412+
413+
== TreeGrid And Hierarchical Data Providers
414+
Vaadin Flow added support for flat hierarchy in [classname]`TreeGrid` and hierarchical data providers.
415+
This required some API removal in Vaadin Flow.
333416

334-
APIs that were deprecated earlier have now been removed. The following linked GitHub issue lists these removals:
417+
[classname]`HierarchyMapper` and [classname]`HierarchicalCommunicationController` have been replaced with the new concept - `Cache`. This new class provides a system for storing data in a hierarchical structure while enabling access in a flattened format for client-side consumption. [methodname]`setRequestedRange` and [methodname]`setParentRequestedRange` have been replaced with a single [methodname]`setViewportRange` which spans all hierarchy levels.
418+
419+
See link:https://github.com/vaadin/platform/issues/7843[TreeGrid Flat Hierarchy Support] and link:https://github.com/vaadin/flow-components/issues/7269[Improving user and developer experience in TreeGrid] for more details.
420+
421+
== Form Filler Add-on
422+
The link:https://github.com/vaadin/form-filler-addon/issues[Form Filler add-on] has been removed from the Vaadin 25 platform. If your project uses it, you can add it as a separate dependency or get the same functionality with much less code using Spring AI to have the LLM directly populate a Java object that you can then use with e.g. [methodname]`binder.readBean()`.
423+
424+
== Polymer Support
425+
426+
In Vaadin 25, the `@polymer/polymer` dependency in default `package.json` is removed by default, if polymer-template module is not found from the project. If the application uses Polymer in add-ons may require to add `@NpmPackage(value = "@polymer/polymer", version = "3.5.2")` or add an import to `package.json` explicitly. Details can be found in link:https://github.com/vaadin/flow/issues/21421[Ensure Flow works without Polymer in v25].
427+
428+
== Frontend Sources Directory
429+
Vaadin uses the [filename]`{project directory}/src/main/frontend/` directory as the default location for frontend sources. Legacy location [filename]`{project directory}/frontend/` is deprecated and a warning will be output if it's used. If you're using the legacy location, please move your files to the new location, or add the `frontendDirectory` parameter and point it to the legacy location. Legacy location support will be removed in a future release.
430+
431+
== Removed Deprecations
335432

336-
- https://github.com/vaadin/flow/issues/21396[Remove deprecated API in Flow 22.0]
433+
APIs deprecated earlier have now been removed. The following linked GitHub issue lists these removals — link:https://github.com/vaadin/flow/issues/21396[Remove deprecated API in Flow 25.0]
337434

338435
== Side Navigation Replaces AppNav and AppNavItem
339436

0 commit comments

Comments
 (0)