错误:Servlet Jar未加载...违规类:javax / servlet / Servlet.class

时间:2010-01-03 00:42:34

标签: java tomcat dependencies

我收到以下错误:

  

INFO:validateJarFile(C:\ dev \ server \ tomcat6 \ webapps   Sempedia \ WEB-INF \ lib \ servlet-api.jar) - jar未加载。参见Servlet Spec 2.3,sectoin 9.7.2。违规类:javax / servlet / Servlet.class

现有的资源表明它是由于与servlet.jar的冲突或在我的情况下命名为servlet-api.jar文件。我已经从/ webapps文件夹中删除了所有其他项目,我已经获取了tomcat6 / lib目录中的servlet-api.jar文件,并将其添加到项目构建路径中,所以我看不到它是怎么回事仍然是一场冲突。

当我尝试运行应用程序时,我得到以下堆栈跟踪。

org.apache.jasper.JasperException:无法为JSP编译类:

  

生成的java文件中的第22行发生错误   对于JspFactory类型,未定义getJspApplicationContext(ServletContext)方法

     

堆栈跟踪:

  org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)       org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)       org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:439)       org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)       org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)       org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)       org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586)       org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)       org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)       org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

6 个答案:

答案 0 :(得分:40)

这是类路径污染的标志。 JSP / Servlet API库依赖于appserver实现,属于Tomcat/lib文件夹中Tomcat 6的情况,并且不会在其他地方移动或复制。正如您现在遇到的那样,它是可移植性问题和类加载冲突的秘诀。 webapp中的库在类加载中具有优先权。如果在那里遇到servlet-api.jar,它会在那里寻找它的依赖关系,但它们显然在那里缺失。

您必须从webapp的Webapp/WEB-INF/lib中删除任何特定于应用服务器的库。您应将特定于webapp的库放在那里。将特定于appserver的库保留在appserver自己的默认类路径中,即您的案例中的Tomcat/lib。保持不变。您最多可以添加要在其中的所有Web应用程序中共享的库,或者甚至更好地在shared.loader中配置Tomcat/conf/catalina.properties

还可以从JDK/libJRE/lib文件夹中删除任何特定于应用服务器和特定于Web应用的库(如果有)。我经常看到一些初学者移动/复制那里的库,因为“否则它不会编译”。您永远不应该在那里复制非JRK / JRE特定的库。这也是便携性问题的秘诀。使用javac编译类时,应使用-cp参数指定依赖库。

更新:如果是IDE(您在谈论“构建路径”时似乎使用了一个),则需要将Web项目与应用程序服务器相关联。例如,在Eclipse中,您可以选择在创建动态Web项目期间执行此操作。您需要在项目创建之前在Eclipse中集成服务器实例。您可以通过Servers视图执行此操作(假设您使用 Eclipse for Java EE 开发人员,否则升级)。您也可以通过项目属性中的 Servers 条目进行更改。选择一个您想用作“默认”服务器的服务器,然后将其库自动包含在项目的构建路径中。绝对没有必要在其他地方复制/移动它们。另请参阅How do I import the javax.servlet API in my Eclipse project?

答案 1 :(得分:20)

正如其他答案所说,这是因为您的WAR包含servlet API类,但它不应该这样做。

如果您使用Maven构建项目,则需要告诉Maven在编译和测试时使servlet API可用,但不要将其包含在WAR中。正如Maven documentation about dependency scope所说,您应该使用Servlet API的provided范围:

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

如果某些依赖项将Servlet API作为编译依赖项引入,您可能还必须明确地将Servlet API排除为传递依赖项:

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>frob-driver-core</artifactId>
        <version>1.0.1</version>
        <exclusions>
            <exclusion>
                <artifactId>servlet-api</artifactId>
                <groupId>javax.servlet</groupId>
            </exclusion>
        </exclusions>
    </dependency>

答案 2 :(得分:4)

不允许部署覆盖Web容器提供的Servlet规范中定义的类。您可以从

下载规范

http://www.jcp.org/aboutJava/communityprocess/final/jsr053/

并检查自己。第9.7.2节在物理页面63上。

Servlet 2.3是一个相当古老的版本,表示Tomcat的古老版本。你有没有特别的理由不使用新的?

答案 3 :(得分:2)

您收到的第一条错误消息是因为Tomcat不需要加载servlet jar,因为它已经有一个并且想要避免冲突。

您通常可以安全地忽略该警告。如果您不希望它出现,则需要从项目中移动servlet jar,而不是使用tomcat中的那个。通过使用tomcat并将其放入项目中,您已设法说服tomcat从您的webapp加载它而不是从它预期的位置加载它,从而导致BalusC的答案中提到的类加载器问题。

编辑:上面的内容经过编辑,以澄清将tomcat中的servlet-api jar放入webapp(和属性BalusC)后发生的情况。

答案 4 :(得分:1)

事实上我有这样的错误和应用程序。由于某些原因,WEB-INF/lib中的某些广告素材有 .JAR (大写)扩展而不是.jar,因此无法开始使用。所以确保所有的罐子都有效。

答案 5 :(得分:0)

排除项和provided依赖项在子项目中不起作用。

如果您在Maven项目中使用继承,则必须在父pom.xml文件中包含此配置。如果使用继承,pom.xml 中将有<parent>...</parent>部分。所以你的父母pom.xml会有类似的东西:

<groupId>some.groupId</groupId>
<version>1.0</version>
<artifactId>someArtifactId</artifactId>
<packaging>pom</packaging>
<modules>
    <module>child-module-1</module>
    <module>child-module-2</module>
</modules>
<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>