简体   繁体   中英

ClassCastException: DispatcherServlet cannot be cast to Servlet

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>

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.

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 eg) with another class loader at the bottom.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM