[英]tomcat7-maven-plugin tomcat7:run java.lang.LinkageError previously initiated loading for a different type with name
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使用Java 1.6编译项目
I am trying to use tomcat7-maven-plugin to run a tomcat dev server using the tomcat7:run goal. 我正在尝试使用tomcat7-maven-plugin使用tomcat7:run目标运行tomcat dev服务器。 When I try to hit the index.jsp for the server, I receive: 当我尝试命中服务器的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. 我已成功使用tomcat7:deploy将相同的代码部署到本地tomcat Windows服务实例。 When I access the local instance of the server, no errors. 当我访问服务器的本地实例时,没有错误。
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; 我无法弄清楚的是冲突的方式/原因/地点; ie, 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. 也就是说,哪些是冲突的罐子,以及当我尝试使用tomcat7:run运行时如何/为什么会发生这种情况,但是当我使用我的本地tomcat实例运行“standalone”时却不会。
pom: 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 project 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 target dir的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);
}
}
Biju Kunjummen answered the question in his comment to my original post. Biju Kunjummen在我对原帖的评论中回答了这个问题。 Thank you Biju Kunjummen! 谢谢Biju Kunjummen! Please vote up his comment. 请将他的评论投票。
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. pom.xml中的servlet-api依赖项需要“提供”范围。 This is because Tomcat already provides (requires and uses itself) the servlet-api dependency. 这是因为Tomcat已经提供(需要并使用自身)servlet-api依赖项。 Maven's dependency scoping rules are defined here: Maven的依赖范围规则定义如下:
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope
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" (ie, with the tomcat7:run goal)? 当我将war部署到本地tomcat实例时,为什么以前的xml工作,而不是“在进程中”运行它(即使用tomcat7:run目标)? 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. 进程服务器运行器中的maven显然以与本地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提供的范围来确保依赖关系不会发生冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.