I am deploying a Spring 6.0.5 on Tomcat 8.5.81 with the following configuration (using web.xml
and org.springframework.web.servlet.DispatcherServlet
).
My web.xml is configured as follows:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dispatcher-config.xml
is as follows:
<mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="/resources/"/> <context:component-scan base-package="org.mainPackage" /> <context:annotation-config/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
And finally pom.xml relevant dependencies are what follows:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>17</java.version>
<tomcat.version>8.5.81</tomcat.version>
<servlet-api.version>3.1.0</servlet-api.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
The root cause of the error being :
java.lang.ClassCastException: class org.springframework.web.servlet.DispatcherServlet cannot be cast to class javax.servlet.Servlet (org.springframework.web.servlet.DispatcherServlet is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4ac6da24; javax.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @28c97a5)
Why this is happening? and how can this issue be solved?
Thanks.
Spring 6 has moved from javax to jakarta completely. With that in mind other of libraries needs to be updated.
Tomcat 8.5 to Tomcat 10.
And JDK 1.8 to JDK17.
Also please keep in mind that any javax libraries need to be replaced with the one that uses jakarta. I think that replacement for that is
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
Or you can simply keep your Tomcat and JDK version but use Spring 5.
So in short
You cannot mix jakarta and javax because simply they are not compatible unless you are ready to rename packages by hand.