Maven:为什么我得到 servlet-api-2.5

Maven: Why am I getting servlet-api-2.5

我正在使用 Maven 创建一个 Web 应用程序,但我遇到了一个问题 - 由于某种原因,我得到了 servlet-api-2.5.jar,这给出了奇怪的异常。从 WAR 存档中删除此文件可解决所有问题,但我试图了解 为什么 它首先存在于此。我在 完整 pom.xml 文件中的 依赖项是:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.sillyfly.webapp</groupId>
    <artifactId>Webapp</artifactId>
    <version>0.1</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>7</source>
                    <target>7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <webXml>web/WEB-INF/web.xml</webXml>
                    <webappDirectory>web</webappDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-jstlel</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-spec</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

和运行 mvn dependency:tree -Dverbose 产量:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - org.sillyfly.webapp:Webapp:jar:0.1
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] org.sillyfly.webapp:Webapp:jar:0.1
[INFO] +- org.glassfish:javax.json:jar:1.0.4:compile
[INFO] +- org.apache.taglibs:taglibs-standard-impl:jar:1.2.5:compile
[INFO] +- org.apache.taglibs:taglibs-standard-jstlel:jar:1.2.5:compile
[INFO] +- org.apache.taglibs:taglibs-standard-spec:jar:1.2.5:compile
[INFO] +- mysql:mysql-connector-java:jar:5.1.38:compile
[INFO] \- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Sat Mar 26 12:12:32 IDT 2016
[INFO] Final Memory: 24M/515M
[INFO] ------------------------------------------------------------------------

没有提及 servlet-api-2.5.jar。 我现在注意到它说的是 jar 而不是 war,所以我想我的问题是双重的: 1. JAR 和 WAR 依赖项是否不同,如果不同,我如何获得 Maven 依赖项插件来显示 WAR 依赖项? 2. 我如何明确告诉 Maven not 包含 servlet-api-2.5.jar?我试过在不同的地方添加排除项,但是因为我不知道为什么它首先在那里,所以它主要是一个猜谜游戏,关于把排除项放在哪里,以及 none 我去过的地方试过有效。

mvn --version 供参考:

Apache Maven 2.2.1 (rdebian-23)
Java version: 1.8.0_72-internal
Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux" version: "4.4.0-1-amd64" arch: "amd64" Family: "unix"

编辑:我更新到 Maven 3.3.9,我仍然得到完全相同的结果。唯一的区别是依赖树显示了各种 apache taglibs 库之间的依赖关系,但仍然没有提到 servlet-api-2.5.

根据您提供的信息我无法重现您的问题,所以根本原因一定是在其他地方。

当从命令行 运行 mvn package 时,您是否看到了额外的 servlet JAR,或者这可能是您的 IDE 的奇怪效果?

如果问题仍然存在,请尽量减少您的应用程序并创建一个独立的项目,例如在 GitHub 上人们可以查看。

顺便说一下,您绝不能在 WEB-INF/lib 中包含 servlet API(不能两次,一次也不能)。始终对 servlet API.

使用 Maven 作用域 provided

罪魁祸首是源 WEB-INF 中的 lib/classes/ 文件夹,其中包含被包含的 jar。这些文件夹是由于错误的 pom 配置而创建的(见下文)。当 运行 Maven.

启用 Maven 调试输出 (mvn -X) 后情况可见

删除这些文件夹解决了我所有的问题。

编辑: 再次获取相同的文件夹后,我找到了原因 - 我使用了 <webappDirectory>,而我应该使用 [=15] =].

通常情况下,您的项目中存在依赖于 servlet-apî.jar 的依赖项。
Maven 的默认行为是我将尝试导入您的依赖项 + 导入依赖项的依赖项。 如果你想排除特定的"sub-dependency",你可以给maven这样的配置:

<dependency>
    <groupId>com.hpsworldwide.mbtrs.switch</groupId>
    <artifactId>DEPENDENCY</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>