TL;DR: I have a Spring MVC Hello, World! application that works on Tomcat 9. The same application on Tomcat 10 gives a 404 error for web request mappings.
The Problem
When deploying a Spring MVC 5 Hello, World! application to Tomcat 10, the application gives a 404 error for web request mappings. The same Hello, World! application works on Tomcat 9. It displays the Hello, World! message on Tomcat 9.
What I Expected
I expected the application to display the Hello, World! message on Tomcat 10.
Environment
Research I Performed
I researched in the Spring Reference Manual, Section on Web Servlet. I also tested Spring MVC Tutorials online. These tutorials worked on Tomcat 9. However, the same tutorials failed on Tomcat 10. I also performed Google search on Tomcat 10. I saw references to Jakarta EE, but I am not sure if this is the source of the issue. Java EE 8 and Jakarta EE 8 are backwards compatible.
How to Reproduce
I created a very basic Hello, World! project to test this out. Here is the code that I'm using for the project.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.spring</groupId>
<artifactId>example-spring</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
</plugins>
</build>
</project>
package com.example;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ProjectInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { PureJavaConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
}
package com.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class PureJavaConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setSuffix(".jsp");
resolver.setPrefix("/WEB-INF/jsp/");
return resolver;
}
}
package com.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class TutorialController {
@GetMapping("/")
public String home() {
return "home";
}
}
<html>
<body>Hello, World! of Spring! <%= java.time.LocalDateTime.now() %></body>
</html>
This project runs okay on Tomcat 9. It displays the Hello, World! message. However, when I run on Tomcat 10, I get a 404 error message.
TL;DR: Spring MVC 5 does not run on Tomcat 10 because of the package renaming from javax.*
to jakarta.*
.
After further research, I was able to find the answer to my question. Spring MVC 5 does not work on Tomcat 10. This is because Tomcat 10 is based on Jakarta EE 9 where package names for APIs have changed from javax.*
to jakarta.*
.
Tomcat 10 mentioned this on the download webpage:
Users of Tomcat 10 onwards should be aware that, as a result of the move from Java EE to Jakarta EE as part of the transfer of Java EE to the Eclipse Foundation, the primary package for all implemented APIs has changed from
javax.*
tojakarta.*
. This will almost certainly require code changes to enable applications to migrate from Tomcat 9 and earlier to Tomcat 10 and later.
For Spring MVC 5, the Spring MVC DispatcherServlet has a dependency on the javax.servlet.*
package namespace. This is using the Java EE 8 javax
package naming. Since Tomcat 10 is based on Jakarta EE 9, the packages for javax
naming are not supported. This explains why Spring MVC 5 does not work on Tomcat 10.
There are GitHub issues filed against the Spring Framework regarding this:
Spring core 5 is not starting on Tomcat 10
Support for Jakarta EE 9 (annotations and interfaces in jakarta.* namespace)
In my case, instead of migrating to Tomcat 10, I will stay on Tomcat 9 until the Spring framework is upgraded to Jakarta EE 9.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With