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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1993493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:13:35  来源:igfitidea点击:

Error: Servlet Jar not Loaded... Offending class: javax/servlet/Servlet.class

javatomcatdependencies

提问by Ankur

I get the following error:

我收到以下错误:

INFO: validateJarFile(C:\dev\server\tomcat6\webapps Sempedia\WEB-INF\lib\servlet-api.jar) - jar not loaded. See Servlet Spec 2.3, sectoin 9.7.2. Offending class: javax/servlet/Servlet.class

信息:validateJarFile(C:\dev\server\tomcat6\webapps Sempedia\WEB-INF\lib\servlet-api.jar) - jar 未加载。请参阅 Servlet 规范 2.3,第 9.7.2 节。违规类:javax/servlet/Servlet.class

The existing resources out there say it is due to a conflict with the servlet.jar or in my case named servlet-api.jar file. I have removed all other projects from the /webapps folder, I have taken the servlet-api.jar file that was in the tomcat6/lib directory and added that and only that to the project build path, so I can't see how there is still a conflict.

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

When I try to run the application I get the following stack trace.

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

org.apache.jasper.JasperException: Unable to compile class for JSP:

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

An error occurred at line: 22 in the generated java file The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory

Stacktrace:

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)

生成的 java 文件中第 22 行发生错误 The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory

堆栈跟踪:

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.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。编译(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)

回答by BalusC

This is a sign of classpath pollution. The JSP/Servlet API libraries are appserver implementation dependent and belongs in case of Tomcat 6 in the Tomcat/libfolder and should in no waybe moved nor duplicated somewhere else. It's recipe for portability trouble and collisions in classloading as you've encountered now. The libraries in webapp have precedence in classloading. If the servlet-api.jaris encountered there, it is in turn looking for its dependencies there, but they were apparently missing in there.

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

You must remove any appserver-specific libraries from the webapp's Webapp/WEB-INF/lib. You should onlyput webapp-specific libraries in there. Keep appserver-specific libraries in the appserver's own default classpath, which is the Tomcat/libin your case. Keep it untouched. You can at most add libraries which you'd like to share among all webapps in there, or even better, configure the shared.loaderin Tomcat/conf/catalina.propertiesfor that.

您必须从 webapp 的Webapp/WEB-INF/lib. 您应该将特定于 webapp 的库放在那里。将特定于应用程序服务器的库保留在应用程序服务器自己的默认类路径中,这就是Tomcat/lib您的情况。保持原样。您最多可以添加您希望在其中的所有 web 应用程序之间共享的库,或者甚至更好的是shared.loaderTomcat/conf/catalina.properties为此配置in 。

Also remove any appserver-specific and webapp-specific libraries from the JDK/liband JRE/libfolders, if any. I've seen too often that some starters move/copy the libraries there because "it otherwise doesn't compile". You should never copy non-JRK/JRE-specific libraries in there. It is recipe for portability trouble as well. When compiling classes with javac, you should use the -cpargument to specify the dependent libraries.

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

Update: in case of an IDE (you seem to use one as you're talking about "build path"), you need to associate the web project with an application server. In Eclipse for example, you have the option to do that during creation of a Dynamic Web Project. You need to integrate the server instance in Eclipse prior to project creation. You can do that through the Serversview (assuming that you're using Eclipse for Java EEdevelopers, else upgrade). You can also change it afterwards through the Serversentry in the project properties. Choose one which you'd like to use as the "default" server and then its libraries will automagically be included in the project's build path. There's absolutely no need to copy/move them somewhere else. See also How do I import the javax.servlet API in my Eclipse project?

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

回答by Jamie McCrindle

The first error message you got was because Tomcat doesn't need to load the servlet jar because it already has one and wants to avoid conflicts.

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

You can usually safely ignore the warning. If you don't want it to appear, you need to move the servlet jar from your project, rather than using the one from tomcat. By taking the tomcat one and putting it into your project, you've managed to convince tomcat to load it from your webapp rather than from from where it was expecting it, causing a classloader issue as mentioned in the BalusC's answer.

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

Edit: The above was edited to clarify what was happening once you put the servlet-api jar from tomcat into your webapp (and attribute BalusC).

编辑:以上内容经过编辑以阐明将 servlet-api jar 从 tomcat 放入 web 应用程序(和属性 BalusC)后发生的情况。

回答by Thorbj?rn Ravn Andersen

You are not allowed to deploy classes that override those defined in the Servlet Specification to be provided by the web container. You can download the specification from

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

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

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

and check for yourself. Section 9.7.2 is on physical page 63.

并自行检查。第 9.7.2 节位于物理第 63 页。

Servlet 2.3 is a rather old version indicating an ancient version of Tomcat. Is there any particular reason you are not using a newer one?

Servlet 2.3 是一个相当旧的版本,表明 Tomcat 的旧版本。您不使用较新的有什么特别的原因吗?

回答by Raedwald

As other answers say, this is because your WAR includes the servlet API classes, but it should not do so.

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

If you are using Maven to build your project you will want to tell Maven to make the servlet API available when compiling and testing, but not to include it in the WAR. As the Maven documentation about dependency scopesays, you should use providedscope for the Servlet API:

如果您使用 Maven 构建您的项目,您需要告诉 Maven 在编译和测试时使 servlet API 可用,但不要将它包含在 WAR 中。正如关于依赖范围Maven 文档所说,您应该provided为 Servlet API使用范围:

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

You might also have to explicitly exclude the Servlet API as a transitive dependency, if some of your dependencies pull in the Servlet API as a compile 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>

回答by lmiguelmh

Exclusions and provideddependencies will not work in child projects.

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

If you are using inheritance in Maven projects you mustinclude this configuration on the parent pom.xmlfile. You will have a <parent>...</parent>section in your pom.xml if you are using inheritance. So you will have something like this in your parent pom.xml:

如果您在 Maven 项目中使用继承,则必须在父pom.xml文件中包含此配置。如果您使用继承,您将<parent>...</parent>在 pom.xml 中有一个部分。所以你的父母会有这样的事情: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>

回答by sergeyan

In fact I had such error and app. wasn't able to get started, because for some reason, some of the jars in WEB-INF/libhad .JAR(upper case) extension instead of .jar. So make sure that all the jars are valid.

事实上我有这样的错误和应用程序。无法开始,因为出于某种原因,某些 jarWEB-INF/lib具有.JAR(大写)扩展名而不是.jar. 所以要确保所有的罐子都是有效的。