How to run Spring Framework 6 applications on a Container

If you want to run your Spring Framework 6 applications (or Spring Boot 3) on the top of a Jakarta EE container there are some requirements you need to comply with. This article discusses them in detail.

The Problem with Jakarta EE packages

If you are deploying your Spring 6 (or Spring Boot 3) applications on the top of a container such as Tomcat 8/9 or JBoss EAP 7.4 then you might hit the following error:

java.lang.NoClassDefFoundError: jakarta/servlet/ServletConnection
	at org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.createServletRequest(MockHttpServletRequestBuilder.java:769)
	at org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.buildRequest(MockHttpServletRequestBuilder.java:663)
	at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:172)
        at org.example.ExampleControllerTest.test(ExampleControllerTest.java:29)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.ClassNotFoundException: jakarta.servlet.ServletConnection  
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 74 more

The Cause

In Spring Framework 6 or Spring Boot 3.0, whenever you need to use the Jakarta EE specification, you should be aware that Spring 6 relies on Jakarta EE 9+ specification. For instance, Spring Boot relies on Jakarta Servlet 6.0 and JPA 3.1 specifications.

The Solution

Firstly, if you manage your own dependencies and do not rely on the starter POMs provided by Spring Boot, it is crucial to update your Maven or Gradle file accordingly. Take care to remove any older Java EE dependencies that are no longer used directly or transitively in your build. Instead, ensure you are using the appropriate jakarta.servlet:jakarta.servlet-api instead of javax.servlet:javax.servlet-api.

Then, if you want to use Spring 6 or Spring Boot 3 you need to deploy applications on a container that has support for Jakarta EE 9 or newer. Besides, you need to update the import statements from javax. * to jakarta.* in your project as well.

Containers that fully support Jakarta EE 9/10 specifications are:

  • WildFly 28
  • Tomcat 10
  • Apache TomEE 9.0
  • OpenLiberty 22
  • Payara Server Community 6

Finally, if you want to run Spring 6 or Spring Boot 3 applications also consider that you need to upgrade your JDK to version 17+. Read more here: https://spring.io/blog/2021/09/02/a-java-17-and-jakarta-ee-9-baseline-for-spring-framework-6