Skip to main content

Seamless Migration: Upgrading to Java 17 and Spring 6

· 6 min read

As highlighted in one of our previous posts, starting with version 11.9, WaveMaker applications will be transitioning to Java 17/21 and Spring 6. This is a significant upgrade, and as noted earlier, regarding the shift from javax to jakarta namespaces, there is a namespace change in the dependent libraries that necessitates the migration of your WaveMaker applications.

This post will guide you through what to expect during the migration process. We'll cover which components are automatically updated by the platform and which areas may require manual intervention. By breaking down the migration of Java classes, dependencies, and other elements, you'll gain a clear understanding of how WaveMaker manages this transition and what steps you can take to ensure a smooth upgrade.

Auto Migration of Java Classes

All Java classes in your application and prefab projects that use the javax namespace will be automatically migrated to the jakarta namespace, ensuring compatibility with the new ecosystem.

Before Migration

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
public class Example {
@NotNull
private String name;
}

After Migration

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
public class Example {
@NotNull
private String name;
}

We are utilising the Eclipse Transformer for this migration, and the transformation process adheres to the rules defined in the jakarta-rename.properties file, which provides a mapping between the namespaces. You can view the file here.

Automated Dependency Migration

In one of our previous release, we introduced a parent POM structure to manage the versions of all dependencies used in WaveMaker applications. With the 11.9 upgrade, the parent POM has been updated with the latest versions of dependencies, which are automatically applied to all WaveMaker projects during the migration process. However, we identified some discrepancies in certain projects, as outlined below:

  • Default App Runtime Dependencies: Many default dependencies your application relies on are already included in the parent POM. During the 11.9 migration, any duplicate dependencies in your application POM that are also present in the parent POM will be removed to avoid redundancy. For instance, if Apache Commons Lang3 is declared in the application POM, it will be removed since it's already included in the parent POM.

  • Dependency Version Management: If a dependency version is declared in the parent POM, both the version and any overrides using placeholders or properties will be removed from the application POM. This ensures that the application inherits the correct version from the parent POM. For example, if spring-security-oauth2-client has its version set through a property like ${spring.security.version}, both the version tag and the property will be removed, allowing the dependency to inherit the latest version from the parent POM.

Before Migration

<properties>
<wavemaker.artifactType>wmapp</wavemaker.artifactType>
<spring.security.version>5.3.39</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>${spring.security.version}</version>
</dependency>
</dependencies>

After Migration

<properties>
<wavemaker.artifactType>wmapp</wavemaker.artifactType>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
</dependencies>
  • Property Management: Any properties that override the dependencies in the parent POM will also be removed to ensure the latest version is used by the application.

Before Migration

<properties>
<wavemaker.artifactType>wmapp</wavemaker.artifactType>
<springFramework.version>5.3.39</springFramework.version>
</properties>

After Migration

<properties>
<wavemaker.artifactType>wmapp</wavemaker.artifactType>
</properties>
  • Migration of Javax Dependencies: Any javax dependencies declared in your application with direct equivalents in jakarta will be migrated automatically. For example javax.mail dependency will be replaced with its equivalent jakarta.mail dependency.

Before Migration

<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
</dependencies>

After Migration

<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
note

As part of the automatic migration to the latest Jakarta libraries, any usage of deprecated or removed methods and classes may result in compilation or runtime issues. These will need to be addressed manually after the upgrade to ensure smooth functionality.

Migration of Connectors

Any default connectors provided by WaveMaker, such as Email or Jasper Reports, present in your application will also be migrated automatically to ensure they remain compatible with the upgraded Spring and Servlet versions.

Migration of Spring Security

In Spring Security 6, a notable change has been made in how the SecurityContext is managed. Previously, the context-saving logic was automatically triggered when a request was completed. However, this responsibility has now shifted to the authentication filters. As a result, if your application includes any custom filters where the SecurityContext or Authentication object is modified, you must ensure that these changes are explicitly updated in the session repository to prevent any issues with saving.

To address this, we have introduced a WMSecurityUtils class that handles the logic for updating the session repository. During the migration, any instance where the SecurityContext is used or modified in your custom code will be replaced with the WMSecurityUtils class to ensure compatibility and proper session management.

Before Migration

SecurityContextHolder.getContext().setAuthentication(authentication);

After Migration

WMSecurityUtils.setAuthentication(authentication);

What requires manual migration?

While most of the migration is handled automatically, some specific cases require manual intervention:

  • Third-Party Libraries Using javax internally: If your application includes third-party libraries that still rely on javax classes internally, they will NOT be automatically migrated during the update. This can lead to compilation or runtime errors. To avoid this, it's highly recommended to update those libraries to newer versions that are compatible with the Jakarta namespace, or replace them with alternative libraries that support the latest standards.

  • Custom Code Using Deprecated Spring/Servlet Classes or Methods: Any custom Java code that uses deprecated classes or methods from older versions of Spring or Servlet, will have to be updated manually to ensure compatibility with Spring 6 and Servlet 6.

  • Custom Connectors: Any custom built connectors in your application needs to be migrated manually.

In case you have added any custom dependencies in your project, it is recommended to run the command mvn dependency:tree to find out if your project still has any javax dependencies either directly or transitively. If found, it is recommended to update to versions that support the jakarta namespace or replace them with suitable alternatives.

Summary

The migration to Java 17 and Spring 6 represents a significant leap forward for WaveMaker applications, ensuring enhanced performance, security, and compatibility with the latest technologies. While the platform automates much of this transition, some areas will still require manual intervention, especially with third-party libraries and custom code as highlighted above.