关于eclipse+tomcat调试时,Servlet Jar not Loaded的问题

转载自:http://stackoverflow.com/questions/1993493/error-servlet-jar-not-loaded


运行时,报错信息如下:


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

原因如下:

大致就是说,tomcat的lib下有servlet的jar包了,你项目里面依赖的servlet jar包不会被加载


The first error message you got was because Tomcat doesn't need to load the servlet jar because italready 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). 


一些解决方案:


This is a sign of classpath pollution. The JSP/Servlet API libraries are appserver implementation dependent and belongs in case of Tomcat 6 in theTomcat/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 shouldonly put webapp-specific libraries in there. Keep appserver-specific libraries in the appserver's own default classpath, which is theTomcat/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 theshared.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 aDynamic Web Project. You need to integrate the server instance in Eclipse prior to project creation. You can do that through theServers view (assuming that you're using Eclipse for Java EE developers, else upgrade). You can also change it afterwards through theServers 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?



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


你可能感兴趣的:(eclipse,tomcat)