ClassCastException:DispatcherServlet无法强制转换为Servlet

时间:2013-07-22 23:45:22

标签: java spring maven servlets pom.xml

我使用maven-eclipse创建了一个新的Spring MVC项目,并抛出以下错误:

(我尝试了一些来自stackoverflow的解决方案,这在我的情况下不起作用。我找不到pom.xml的一些问题。我添加了servlet-api的提供范围,并尝试了哪些也没有用。)

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

我的pom.xml如下:

<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>

我的web.xml如下:

<?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>

4 个答案:

答案 0 :(得分:20)

更改

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

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

provided有此描述:

  

这很像编译,但表示你期望JDK或者   容器在运行时提供依赖性。例如,何时   您可以为Java Enterprise Edition构建Web应用程序   设置对Servlet API和相关Java EE API的依赖   提供范围是因为Web容器提供了这些类。这个   scope仅在编译和测试类路径上可用,并且是   不是过渡性的。

来自maven docs

。你基本上是在告诉Maven提供用于编译的jar,但是,在运行时,使用其他一些servlet容器的jar。

答案 1 :(得分:2)

在您的情况下,ClassCastException似乎是因为类被不同的类加载器加载。比如说,你的WEB-INF / lib错误地包含了servlet-api.jar,并且你已经为你的webapp类加载器设置了PARENT_LAST为true。如果您在像WAS这样的应用程序服务器上运行,这意味着您将使用一个类加载器(顶部的一些类加载器)和实现(servlet-api jar只是一个例子)加载接口,底部有另一个类加载器。 / p>

答案 2 :(得分:0)

您使用的是哪个应用服务器?我认为Servlet jar文件应该由你的应用程序提供。

答案 3 :(得分:0)

将范围保持为“已提供”并尝试将该jar保留在tomcat / lib文件夹中。这是因为各个war的每个类加载器都试图分别加载自己的Servlet-api类,而不是在容器级加载Servlet-api类的应用程序类加载器。

因此,如果您可以将jar移动到CATALINA_HOME / lib.you只需要由应用程序类加载器加载的类集,并且所有战争都会引用相同的版本。

范围'提供'传达给战争级别的类加载器,它所需的类已经由应用程序类加载器加载,并且坚持在其战争级别的类加载器可能不需要为它创建导致类转换的单独实例或版本例外