我收到以下错误:
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)
答案 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/lib
和JRE/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>