tomcat7-maven-plugin tomcat7:run java.lang.LinkageError先前启动了针对名称不同的类型的加载

问题描述 投票:6回答:2

Windows Server 2008 R2,64Apache Maven 2.2.1Java版本:1.6.0_26JAVA_HOME:C:\ Program Files \ Java \ jdk1.6.0_26Tomcat 7.0使用Java 1.6编译项目]

我正在尝试使用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)

我已成功使用tomcat7:deploy将相同的代码部署到本地tomcat Windows服务实例。当我访问服务器的本地实例时,没有错误。

我的代码通过此Maven依赖项依赖于javax.servlet.http.HttpServlet:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>

鉴于我遇到的错误,我很确定此依赖项存在类加载冲突。我不知道是如何/为什么/在哪里发生冲突。即,哪里有冲突的罐子?当我尝试使用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>

项目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>

来自Maven目标目录的tomcat web.xml Web应用程序声明:

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

实际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);
    }
}
java tomcat maven classpath classloader
2个回答
15
投票

Biju Kunjummen在对我的原始帖子的评论中回答了这个问题。谢谢Biju Kunjummen!请对他的评论投票。

我对自己的问题的回答仅提供更多细节。

pom.xml中的servlet-api依赖项需要“提供的”范围。这是因为Tomcat已经提供(需要并使用)servlet-api依赖项。 Maven的依赖范围定义规则在这里定义:

http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

更正后的servlet-api依赖关系xml:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

为什么当我将战争部署到本地tomcat实例而不是“在进程中”运行它(即,使用tomcat7:run目标)时,以前的xml为什么起作用?我对此没有确切答案。流程服务器运行程序中的行家显然以与本地tomcat实例不同的方式加载依赖项。

我的收获是,即使我可能需要依赖项来编译某些代码,但我也要记住,如果要将代码部署到某种容器中,则需要使用maven提供的作用域确保依赖性不会冲突。


0
投票

对我来说,它的工作方式像。

         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

仅在依赖项中添加范围

© www.soinside.com 2019 - 2024. All rights reserved.