tomcat7-maven-plugin tomcat7:run java.lang.LinkageError 先前已启动加载具有名称的不同类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11145710/
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
tomcat7-maven-plugin tomcat7:run java.lang.LinkageError previously initiated loading for a different type with name
提问by Hawkeye Parker
Windows Server 2008 R2, 64 Apache Maven 2.2.1 Java version: 1.6.0_26 JAVA_HOME: C:\Program Files\Java\jdk1.6.0_26 Tomcat 7.0 Compiling project with Java 1.6
Windows Server 2008 R2, 64 Apache Maven 2.2.1 Java 版本:1.6.0_26 JAVA_HOME:C:\Program Files\Java\jdk1.6.0_26 Tomcat 7.0 Compiling project with Java 1.6
I am trying to use tomcat7-maven-plugin to run a tomcat dev server using the tomcat7:run goal. When I try to hit the index.jsp for the server, I receive:
我正在尝试使用 tomcat7-maven-plugin 来运行使用 tomcat7:run 目标的 tomcat 开发服务器。当我尝试访问服务器的 index.jsp 时,我收到:
HTTP Status 500 - java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest"
type Exception report
message java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest"
description The server encountered an internal error (java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest") that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest"
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:343)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
root cause
java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/jasper/servlet/JasperLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest"
java.lang.Class.getDeclaredMethods0(Native Method)
java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
java.lang.Class.getDeclaredMethods(Class.java:1791)
org.apache.catalina.util.Introspection.getDeclaredMethods(Introspection.java:108)
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:172)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
I have successfully used tomcat7:deploy to deploy the same code to a local tomcat Windows service instance. When I access the local instance of the server, no errors.
我已经成功地使用 tomcat7:deploy 将相同的代码部署到本地 tomcat Windows 服务实例。当我访问服务器的本地实例时,没有错误。
My code depends on javax.servlet.http.HttpServlet via this maven dependency:
我的代码通过这个 maven 依赖依赖于 javax.servlet.http.HttpServlet:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
Given the error I'm getting, I'm pretty sure there's a class loading conflict for this dependency. What I can't figure out is the how/why/where of the conflict; i.e., where are the jars which are conflicting, and how/why is this happening when I try to run with tomcat7:run, but not when I run "standalone" using my local tomcat instance.
鉴于我得到的错误,我很确定这个依赖项存在类加载冲突。我想不通的是冲突的方式/原因/地点;即,冲突的 jar 在哪里,以及当我尝试使用 tomcat7:run 运行时如何/为什么会发生这种情况,但当我使用本地 tomcat 实例运行“独立”时则不会。
pom:
绒球:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.moring.gloak</groupId>
<artifactId>gloak-registration</artifactId>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>gloak-registration Maven Webapp</name>
<build>
<finalName>gloak-registration</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-SNAPSHOT</version>
<configuration>
<server>local_tomcat</server>
<url>http://localhost:9280/manager/text</url>
<update>true</update>
<port>9280</port>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>people.apache.snapshots</id>
<url>http://repository.apache.org/content/groups/snapshots-group/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</project>
project web.xml
项目 web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>registrationServlet</servlet-name>
<servlet-class>com.moring.gloak.web.register.RegistrationServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>registrationServlet</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>
</web-app>
tomcat web.xml webapp declaration from maven target dir:
来自 maven 目标目录的 tomcat web.xml webapp 声明:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
actual servlet code:
实际的servlet代码:
package com.moring.gloak.web.register;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public final class RegistrationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("index.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> messages = new HashMap<String, String>();
request.setAttribute("messages", messages);
// Get and validate name.
String serviceName = request.getParameter("serviceName");
if (serviceName == null || serviceName.trim().isEmpty()) {
messages.put("name", "Please enter service name");
} else if (!serviceName.matches("\p{Alnum}+")) {
messages.put("name", "Please enter alphanumeric characters only");
}
if (messages.isEmpty()) {
messages.put("success", String.format("Service name is %s", serviceName));
}
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
回答by Hawkeye Parker
Biju Kunjummen answered the question in his comment to my original post. Thank you Biju Kunjummen! Please vote up his comment.
Biju Kunjummen 在他对我原帖的评论中回答了这个问题。谢谢碧菊坤珠门!请投票赞成他的评论。
My answer to my own question is only providing a bit more detail.
我对自己问题的回答只是提供了更多细节。
The servlet-api dependency in the pom.xml needed the "provided" scope. This is because Tomcat already provides (requires and uses itself) the servlet-api dependency. Maven's dependency scoping rules are defined here:
pom.xml 中的 servlet-api 依赖项需要“提供的”范围。这是因为 Tomcat 已经提供(需要并使用自己)servlet-api 依赖项。Maven 的依赖范围规则在这里定义:
The corrected servlet-api dependency xml:
更正后的 servlet-api 依赖关系 xml:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
Why did the previous xml work when I deployed my war to a local tomcat instance, as opposed to running it "in process" (i.e., with the tomcat7:run goal)? I don't have an exact answer for this. The maven in process server runner is clearly loading up dependencies in a different way than the local tomcat instance.
为什么当我将我的 war 部署到本地 tomcat 实例时,以前的 xml 可以工作,而不是“在进程中”运行它(即,使用 tomcat7:run 目标)?对此我没有确切的答案。maven in process server runner 显然以不同于本地 tomcat 实例的方式加载依赖项。
My takeaway from this is that even though I may need a dependency to compile some code, I need to keep in mind that, if I'm deploying that code into some kind of container, I need to use maven's provided scope to make sure the dependencies don't collide.
我从中得出的结论是,即使我可能需要依赖项来编译某些代码,但我需要记住,如果我将该代码部署到某种容器中,我需要使用 maven 提供的范围来确保依赖不冲突。
回答by Pratik Gaurav
for me it worked like.
对我来说它像。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
simply adding the scope in the dependency
只需在依赖项中添加范围