13

I have created a new Spring MVC project using maven-eclipse and the following error is thrown:

(I tried some solutions from the stackoverflow which is not working in my case. Some problem with the pom.xml which I could not find. I added provided scope for the servlet-api and tried which was not working either.)

SEVERE: Servlet /Remindem threw load() exception
java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet 
  cannot be cast to javax.servlet.Servlet

My pom.xml is as follows:

<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.org</groupId>
<artifactId>Remindem</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>Remindem</name>
<url>http://maven.apache.org</url>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.0.0.Beta2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>

    <!-- Spring framework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.6</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>2.5.6</version>
        <scope>compile</scope>

    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.3.RELEASE</version>
        <scope>compile</scope>
    </dependency>


    <!-- Spring MVC framework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>2.5.6</version>
        <scope>compile</scope>
    </dependency>

    <!-- JSTL -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-api</artifactId>
        <version>7.0.19</version>
    </dependency>
</dependencies>

<build>
    <plugins>
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.0</version>
    <configuration>
      <url>http://localhost:8080/Remindem</url>
    </configuration>
  </plugin>
    </plugins>
</build>

My web.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Remindem</display-name>
<session-config>
    <session-timeout>
        30
    </session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

     <servlet>
        <servlet-name>svn</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/SpringAppServlet.xml               
            </param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
</servlet> 

 <servlet-mapping>
    <servlet-name>svn</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping> 

 <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Arun
  • 1,176
  • 5
  • 20
  • 48

4 Answers4

23

Change

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>compile</scope>
</dependency>

to

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

provided has this description:

This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.

from the maven docs. You're basically telling Maven to provided the jar for compilation, but, at runtime, use some other, the servlet container's, jar.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    I changed it. But still it throws the same error. Do I have to change anything? – Arun Jul 23 '13 at 14:39
  • @user What container version are you on? Try cleaning and rebuilding your project in Eclipse and with Maven. – Sotirios Delimanolis Jul 23 '13 at 14:41
  • 1
    I am not sure which container version I am using. But, this is how I run. I run maven clean, maven install and then do a maven build for which I supply the goal as tomcat:run – Arun Jul 23 '13 at 15:17
  • Is there anything you need from your maven `tomcat` dependency? If not, remove it. Something is messing around with your Servlet jar versions. – Sotirios Delimanolis Jul 23 '13 at 15:22
  • Also, please update your spring versions to all be the same as much as possible. – Sotirios Delimanolis Jul 23 '13 at 17:08
  • Still the same error. Jul 23, 2013 1:45:51 PM org.apache.catalina.startup.Embedded start INFO: Starting tomcat server Jul 23, 2013 1:45:51 PM org.apache.catalina.core.StandardEngine start INFO: Starting Servlet Engine: Apache Tomcat/6.0.29 Jul 23, 2013 1:45:52 PM org.apache.catalina.core.ApplicationContext log INFO: Marking servlet svn as unavailable Jul 23, 2013 1:45:52 PM org.apache.catalina.core.StandardContext loadOnStartup SEVERE: Servlet /Remindem threw load() exception java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servle – Arun Jul 23 '13 at 18:48
  • It worked by changing the scope as provided... There was a problem with the attribute name in contextParam in web.xml.. Thanks for the help – Arun Jul 24 '13 at 01:42
  • This resolved the same issue for me. Can you provide more clarification as to why (i.e., how you knew changing it to provided would resolve this type of issue)? – Woodchuck Dec 22 '18 at 22:13
2

In your case, ClassCastException seems to be because of classes being loaded by different classloaders. Say, you have the servlet-api.jar included by mistake in your WEB-INF/lib and you had set PARENT_LAST true for your webapp class loader. If you are running on an application server like WAS, this would mean you are loading interface with one class loader (some class loader at the top) and implementation (servlet-api jar just an e.g.) with another class loader at the bottom.

0

Keep scope as 'provided' and try keeping that jar in tomcat/lib folders. This is because of each class loader of respective war tries to load its own Servlet-api classes separately,compared to application class loader which loads the Servlet-api classes at container level.

So if u can make the jar moved to CATALINA_HOME/lib.you have required set of classes loaded by application class loader only and same version will be referred across by all wars.

scope 'provided' conveys to class loader at war level that the classes required for this is already loaded by application class loader and insists class loader at its war level may not required to create separate instances or version for it that cause class cast exception

User 4.5.5
  • 1,311
  • 3
  • 12
  • 20
-1

Which application server you are using? I think Servlet jars files should be provide by your application srver.

Philip Puthenvila
  • 512
  • 1
  • 8
  • 19