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

我正在尝试使用 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 实例运行“独立”时不会发生这种情况。

起居室:

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

实际的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);
    }
}
4

2 回答 2

15

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 实例时,以前的 xml 工作,而不是“在进程中”运行它(即,使用 tomcat7:run 目标)?对此我没有确切的答案。进程服务器运行器中的 maven 显然以不同于本地 tomcat 实例的方式加载依赖项。

我从中得出的结论是,即使我可能需要一个依赖项来编译一些代码,但我需要记住,如果我将该代码部署到某种容器中,我需要使用 maven 提供的范围来确保依赖项不会发生冲突。

于 2012-06-22T00:00:10.327 回答
1

对我来说,它就像。

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

只需在依赖项中添加范围

于 2019-10-17T10:54:18.440 回答