Index

Upgrade Java version

Upgrade to Java 21 17 on your development machine. 

Java 21 compiler raises the following warnings on classes generated by Gradle plugin org.openapi.generator:

  • [this-escape] possible 'this' escape before subclass is fully initialized
  • [serial] non-transient instance field of a serializable class declared with a non-serializable type

Meanwhile these warnings are fixed (there's a Pull Request for the former), since our projects have compiler blocking warnings (enforced by javac option -Werror) we have to fallback to Java LTS version 17.

E.g. you can install OpenJDK on apt-based systems: 

sudo apt install openjdk-17-jdk

or using brew:

brew install openjdk@17

You can use either jEnv or java-update-alternatives to manage multiple Java versions on your development machine.

Upgrade Project

CI/CD Integration

Open a terminal in project's root folder and create a new branch with suffix -next, e.g.,

git checkout -b feature/baselib3-next

The suffix -next ensures the CI/CD platform will handle any remote push through the Java 21 17 pipeline.

This is a temporary solution, until the project will be fully migrated. Please contact DevOps before merging to master branch.

Upgrade Gradle binary

Use the wrapper task provided by Gradle to upgrade.

Open a terminal in project’s folder and enter the following command:

./gradlew wrapper --gradle-version 8.8
# check upgrade was successful
./gradlew -version 

Set IntelliJ IDEA SDK version 

Open File -> Project Structure, go to Project Settings -> Project and set SDK: 21 17:

Then ensure you have Language level: Project default under all modules listed in Project Settings -> Modules:

Now reload your Gradle project, then open File -> Settings, and check the following: 

  • go to option Build, Execution, Deployment -> Build Tools -> Gradle, check you have Gradle JVM: Project SDK (21 17):

  • go to option Build, Execution, Deployment -> Compiler -> Java Compiler, check you have Project bytecode version: 21 17

Update settings.gradle

Pick the latest available baselib3 tag from https://baltig.infn.it/sysinfo_org/sw/baselib3/-/tags and set the related variable, e.g.:

gradle.ext.baselibVersion = "3.3.4"

Fix reference to baselib3-catalog:

// Replace the following string:
// from("it.infn.sisinfo.microservice:baselib-catalog:${gradle.ext.baselibVersion}")
// with:
from("it.infn.sisinfo.microservice:baselib3-catalog:${gradle.ext.baselibVersion}")

Update build.gradle

Set Java compatibility version

def javaSourceCompatibility = JavaVersion.VERSION_17
def javaTargetCompatibility = JavaVersion.VERSION_17

Fix reference to baselib3

dependencies {
	// Replace the following strings:
	// implementation("it.infn.sisinfo.microservice:baselib:${BASELIB_VERSION}")
	// implementation("it.infn.sisinfo.microservice:baselib:${BASELIB_VERSION}:mongodb")
	// testImplementation testFixtures("it.infn.sisinfo.microservice:baselib:${BASELIB_VERSION}")
	// with:
	implementation("it.infn.sisinfo.microservice:baselib3:${BASELIB_VERSION}")
	implementation("it.infn.sisinfo.microservice:baselib3:${BASELIB_VERSION}:mongodb")
	testImplementation testFixtures("it.infn.sisinfo.microservice:baselib3:${BASELIB_VERSION}")
}

OpenApi Generator

If you are using Gradle plugin org.openapi.generator (exported by baselib3-catalog as plugins.openapi.generator) you'll get the following error:

  • Cannot resolve symbol 'javax.annotation.Generated'.

The javax.annotation package was part of Java EE (now Jakarta EE) and has been removed from JDK 11, you now have to explicitly add it in your dependencies (check for newer versions):

dependencies {
    implementation 'javax.annotation:javax.annotation-api:1.3.2'
	...
}    

Mongock

If you are using mongock, use the following dependencies (check whether there are newer versions):

dependencies {
    implementation "io.mongock:mongock-springboot:5.4.3"
    implementation "io.mongock:mongodb-springdata-v4-driver:5.4.3"
	...
}

baselib-identity-authorization

Library baselib-identity-authorization has been integrated into baselib3, so you must remove the dependency:

dependencies {
	// Remove the following line:
    // implementation "it.infn.sisinfo.microservice:baselib-identity-authorization:1.0.5"
    ...
}

SpringBoot managed versions

Your current versions overridings are probably superseded, try comment them all or have a look at an already upgraded project (e.g. RATP build.gradle) to check if there are any needed overridings:

// Your current overridings are probably superseded, e.g.:
// ext['kafka.version'] = '3.6.0'
// ext['snakeyaml.version'] = '1.33'

Other fixes

Ensure cyclonedxBom settings match the following:

cyclonedxBom {
    includeConfigs = ["runtimeClasspath"]
    skipConfigs = ["compileClasspath", "testCompileClasspath"]
    outputName = "bom"
    outputFormat = "all"
}

Moreover, you can remove the following section:

if (JavaVersion.current().isJava8Compatible()) {
    allprojects {
        tasks.withType(Javadoc) {
            options.addStringOption('Xdoclint:none', '-quiet')
        }
    }
}

Optionally, you can fix some gradle syntax deprecations, e.g.:

# The following is deprecated:
# task checkInfnDependency(type: Exec) { ... }
# replace with:
tasks.register('checkInfnDependency', Exec) { ... }

In general, have a look at RATP build.gradle to check if it matches your project's build.gradle file.

Update Source Code

Jakarta EE

Jakarta EE now uses jakarta packages rather than javax, so you have to update package names throughout your code, e.g., javax.servlet.ServletException becomes jakarta.servlet.ServletException.

At this stage you can launch a build and then fix javax import errors.

Apache HTTP Client

Apache HttpClient was last updated on Nov 30 2022 and has been superseded by HttpClient5 which is being actively maintained.

The HttpClient5 library is a public dependency of baselib3, so your project's modules also have access to the library and you only have to change java imports from org.apache.http.client.HttpClient to org.apache.hc.client5.http.classic.HttpClient.

java.net.URL

Starting with JDK 20, the constructor java.net.URL(String) is deprecated.

The recommended way to create a URL instance is to use URI to validate the URL syntax and then convert it to a URL: (new java.net.URI(urlString)).toURL().

KafkaOperations

Previously, methods in KafkaOperations returned ListenableFuture, but they have been changed to return CompletableFuture in spring-kafka version 3.0.

The usingCompletableFuture() method, which was introduced in version 2.9 to facilitate migration by providing the same methods with CompletableFuture return types, is no longer available in version 3.0 2.

Therefore if you encounter error cannot find symbol usingCompletableFuture() just remove the call in your code, e.g., rewrite op.usingCompletableFuture().send(...) to op.send(...).

ListenableFuture

In Spring Framework 6.0, org.springframework.util.concurrent.ListenableFuture is deprecated in favor of java.util.concurrent.CompletableFutureso change your code accordingly if you encounter deprecation warnings.

Spring Security

@EnableWebSecurity

In Spring Security 6.0, @Configuration is removed from @EnableWebSecurity, @EnableMethodSecurity, @EnableGlobalMethodSecurity and @EnableGlobalAuthentication.

Therefore, wherever you are using one of these annotations, you may need to add @Configuration, e.g.:

@EnableMethodSecurity
@Configuration // Add this annotation
public class MyConfiguration {
    ...
}

Deprecations

The following code block shows how to change some deprecated methods:

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	// Deprecated:
	// http.csrf().disable();
    // http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    // http.authorizeRequests().anyRequest().permitAll();
	// Change to:
    http.csrf(AbstractHttpConfigurer::disable);
	http.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
	http.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll());
    ...
}

Configuration Properties Migration

With Spring Boot 3.0, a few configuration properties were renamed/removed and developers need to update their application.properties/application.yml accordingly.

Spring Boot provides a spring-boot-properties-migrator module. Once added as a dependency to your project, this will not only analyze your application’s environment and print diagnostics at startup, but also temporarily migrate properties at runtime for you.

You can add the migrator by adding the following to your build.gradle:

runtimeOnly 'org.springframework.boot:spring-boot-properties-migrator'

Launch application, look for suggested properties migration in application's logs and apply them to your properties file.

Once you’re done with the migration, make sure to remove this module from your project’s dependencies.


  • No labels