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 dev サーバーを実行しようとしています。サーバーの 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>

私が得ているエラーを考えると、この依存関係にはクラスの読み込みの競合があると確信しています。私が理解できないのは、競合の方法/理由/場所です。つまり、競合しているjarはどこにあり、tomcat7:runで実行しようとするとどのように/なぜこれが起こるのですか?

ポンポン:

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

実際のサーブレット コード:

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>

war をローカルの tomcat インスタンスにデプロイしたときに、以前の xml が機能したのはなぜですか? これに対する正確な答えはありません。プロセス サーバー ランナーの maven は明らかに、ローカルの tomcat インスタンスとは異なる方法で依存関係をロードしています。

ここからの私の結論は、一部のコードをコンパイルするために依存関係が必要になる場合がありますが、そのコードを何らかのコンテナーにデプロイする場合は、maven の提供されたスコープを使用して、依存関係は衝突しません。

于 2012-06-22T00:00:10.327 に答える