Skip to content

Upgrading Spring Boot Apps to Java 24

mmackaysearch edited this page Feb 25, 2026 · 16 revisions

Below are the steps outlined to upgrade a Spring Boot application to Java 24.

NOTE: The version numbers here are updated as of time of writing (07/01/2025) and may be subject to change

Current Version Numbers for Dependencies

  • spring-boot-version: 3.5.9
  • spring-framework: 7.0.3
  • java-version: 24
  • h2database-version: 2.3.232
  • mysql-connector-version: 9.3.0
  • log4j-version: 2.25.3
  • junit-jupiter-engine-version: 5.13.2
  • junit-vintage-engine-version: 5.13.2
  • junit-platform-launcher-version: 5.13.2
  • commons-logging-version: 1.3.5
  • commons-dbcp2-version: 2.13.0
  • commons-codec-version: 1.18.0
  • maven-compiler-plugin: 3.14.0
  • maven-bundle-plugin: 6.0.0
  • maven-surefire-plugin: 3.5.3
  • slf4j-version: 2.0.17
  • commons.lang3.version: 3.18.0
  • commons.text.version: 1.13.1
  • commons-io-version: 2.19.0
  • xmlunit-version: 2.10.3
  • wss4j-version: 4.0.0
  • apache-commons-codec-version: 1.18.0
  • camel-version: 4.17.0
  • cxf-version: 4.1.4
  • dom4j-version: 2.2.0
  • httpcomponents.version: 5.5
  • saxon-version: 12.7
  • xmlunit.version: 2.10.3
  • jakarta.mail.version: 2.0.1
  • joda.time.version: 2.14.0
  • angus-mail: 2.0.4
  • ojb-common-version: [6.0.0,)
  • ojb-camel-common-version: [4.0.0,)
  • ojb-valcour-common-version: [3.0.0,)
  • ojb-resources-common-version: [3.0.0,)
  • h2-mock-database-version: [5.0.0,)
  • ojb-fedquery-common-version: [5.0.0,)

Step 1: Update the pom.xml

Using the dependency versions outlined above, update all of the version numbers for any dependency listed in the list above.

At the top of the pom.xml file up the major version by one to show the upgrade to Java 24, for example:

<version>5.0.15</version>

becomes

<version>6.0.0</version>

Add this dependency and version definition if it is not present:

<dependency>
   <groupId>joda-time</groupId>
   <artifactId>joda-time</artifactId>
   <version>${joda.time.version}</version>
</dependency>

If there is a dependencyManagement portion of the pom.xml present, add only the dependency portion of this under it. Otherwise, add this whole code snippet:

        <dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.junit</groupId>
				<artifactId>junit-bom</artifactId>
				<version>5.13.2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

There a few things to remove from this file if they are present as well, remove the following if it is present anywhere in the pom.xml file:

Versions:

<osgi-core-version>1.4.0</osgi-core-version>
<maven-bundle-plugin-version>2.4.0</maven-bundle-plugin-version>

Dependencies:

<dependency>
    <groupId>org.apache.felix</groupId>
    <artifactId>org.osgi.core</artifactId>
    <version>${osgi-core-version}</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <version>${spring-version}</version>
</dependency>

Plugins:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>${maven-bundle-plugin-version}</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Export-Package>org.ojbc.util.*</Export-Package>
        </instructions>
    </configuration>
</plugin>

There are also a few dependencies that can be found that need to have their groupId and/or their packageId changed, below is the following that is documented thus far:

		<dependency>
			<groupId>org.codehaus.woodstox</groupId>
			<artifactId>woodstox-core-asl</artifactId>
			<version>4.4.1</version>
		</dependency>

becomes
		<dependency>
			<groupId>com.fasterxml.woodstox</groupId>
			<artifactId>woodstox-core</artifactId>
			<version>7.1.1</version>
		</dependency>


		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>${httpcomponents.version}</version>
		</dependency>
becomes
		<dependency>
			<groupId>org.apache.httpcomponents.client5</groupId>
			<artifactId>httpclient5</artifactId>
			<version>${httpcomponents.version}</version>
		</dependency>

		<dependency>
			<groupId>xmlunit</groupId>
			<artifactId>xmlunit</artifactId>
			<version>${xmlunit.version}</version>
			<scope>test</scope>
		</dependency>
becomes
		<dependency>
			<groupId>org.xmlunit</groupId>
			<artifactId>xmlunit-legacy</artifactId>
			<version>${xmlunit.version}</version>
			<scope>test</scope>
		</dependency>

After this is done. Update the Maven project (On Eclipse this is done by right clicking on the root directory of the project, then going Maven -> Update Project...)

Step 2: Organize imports on Java classes.

After updating the Java classes, it is expected there will be a decent amount of classes on your IDE showing errors. To fix this, first make sure all of the imports are updated. On Mac Eclipse, this can be done with the command CMD->Shift->O (Letter not number 0).

Step 3: Run a Maven Install on the project.

Through Maven Install it is also configured to automatically run the JUnit tests. If those tests fail, it indicates that there is additional refactoring to be done.

Below will have some project specific changes that have to get made, if the error is not included here it may require additional research.

Otherwise, if the Maven Install is successful, the project should then be good for the time being!

Step 4: Push Docker Image

Modifications must be made to the Dockerfile and yaml file before building a Docker image:

  • In Dockerfile: Change FROM ojbc/java8-server-base to FROM eclipse-temurin:24.0.2_12-jre-alpine-3.22
  • In yaml file: For the configurations with the corresponding component name, change
build: ./[component-name]

to

build: 
      context: ./[component-name]
      dockerfile: Dockerfile
      platforms:
          - linux/amd64/v2

Then, you may build and push the Docker image

Additional Dependency Specific Steps

httpclient5

There are quite a few changes to make if this dependency is present and used.

Here are what is documented thus far:

  • Change HttpClient import to CloseableHttpClient
  • Change any instance of an Http REST call class (i.e. HttpPost) that uses the method setEntity to use this declaration:
post.setEntity(new StringEntity(payload, ContentType.DEFAULT_TEXT));
  • If the HttpClient object calls the execute method add/modify the following:
HttpResponse response = client.execute(post);

to

BasicHttpClientResponseHandler responseHandler = new BasicHttpClientResponseHandler();
String response = client.execute(post, responseHandler);
  • If there is an SSL Context Builder used for keystore/truststore configuration and uses the loadTrustMaterial, add a null parameter to the method call:
sslContextBuilder.loadTrustMaterial(truststore, null);
  • If there is an SSLConnectionSocketFactory object declared, change it to use the following:
For example:

SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,new AllowAllHostnameVerifier());
		
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();

becomes:

DefaultClientTlsStrategy socketFactory = new DefaultClientTlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE);Add commentMore actions
		
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilderAdd commentMore actions
				.create().setTlsSocketStrategy(socketFactory);

CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManagerBuilder.build())
				.build();

  • In JUnit tests, LocalTestServer becomes ClassicTestServer
  • Methods to get hostname/port from a test server are changed to the below:
String host = server.getInetAddress().getHostName();
int port = server.getPort();

Joda Date Time

If there are any complaints about Joda Date Time not being declared, it must be converted from a Java DateTime object to a Joda DateTime object. There are many variables at play for this but as an example this is how to convert a Java Instant object to a Joda Date Time object:

validFrom = assertion.getSaml2().getConditions().getNotBefore();

becomes

validFrom = new DateTime(assertion.getSaml2().getConditions().getNotBefore().toEpochMilli(), DateTimeZone.getDefault());

xml file updates

If there are any errors regarding Bean construction, CxfHeaderFilterStrategy, AllowAllHostnameVerifier, or .xml files, we need to update the xml files in src/main/resources/META-INF and src/test/resources/META-INF.

http://www.springframework.org/schema/util/spring-util-3.0.xsd

becomes

http://www.springframework.org/schema/util/spring-util.xsd
http://camel.apache.org/schema/spring/camel-spring.xsd

becomes

http://camel.apache.org/schema/spring/camel-spring-4.12.0.xsd

becomes

```
xmlns:cxf="http://camel.apache.org/schema/cxf"

becomes

xmlns:cxf="http://camel.apache.org/schema/cxf/jaxws"
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd

becomes

http://camel.apache.org/schema/cxf/jaxws http://camel.apache.org/schema/cxf/jaxws/camel-cxf-spring-soap-4.12.0-spring.xsd
<bean id="dropAllMessageHeadersStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy">

becomes

<bean id="dropAllMessageHeadersStrategy" class="org.apache.camel.component.cxf.transport.header.CxfHeaderFilterStrategy">

Clone this wiki locally