Error: Servlet Jar not Loaded… Offending class: ja

2019-01-03 06:49发布

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

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.

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

org.apache.jasper.JasperException: Unable to compile class for 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)

6条回答
够拽才男人
2楼-- · 2019-01-03 07:06

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/lib folder and should in no way be 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.jar is encountered there, it is in turn looking for its dependencies there, but they were apparently missing in there.

You must remove any appserver-specific libraries from the webapp's Webapp/WEB-INF/lib. You should only put webapp-specific libraries in there. Keep appserver-specific libraries in the appserver's own default classpath, which is the Tomcat/lib in 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.loader in Tomcat/conf/catalina.properties for that.

Also remove any appserver-specific and webapp-specific libraries from the JDK/lib and JRE/lib folders, 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 -cp argument to specify the dependent libraries.

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 Servers view (assuming that you're using Eclipse for Java EE developers, else upgrade). You can also change it afterwards through the Servers entry 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?

查看更多
萌系小妹纸
3楼-- · 2019-01-03 07:08

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/lib had .JAR (upper case) extension instead of .jar. So make sure that all the jars are valid.

查看更多
Emotional °昔
4楼-- · 2019-01-03 07:10

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

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

and check for yourself. Section 9.7.2 is on physical page 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?

查看更多
聊天终结者
5楼-- · 2019-01-03 07:18

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.

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.

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

查看更多
劫难
6楼-- · 2019-01-03 07:21

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

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 scope says, you should use provided scope for the 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:

    <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>
查看更多
来,给爷笑一个
7楼-- · 2019-01-03 07:23

Exclusions and provided dependencies will not work in child projects.

If you are using inheritance in Maven projects you must include this configuration on the parent pom.xml file. 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:

<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>
查看更多
登录 后发表回答