依赖项包含在编译项目中的哪些Maven依赖范围中?

5
例如,如果我将BukkitApi jar作为Maven项目的依赖项,并将依赖范围设置为provided、compile、system、runtime或test,那么BukkitAPI将包含在编译输出中的哪些范围内?

1
编译后的输出是什么?你在说哪个阶段?例如,如果你将范围设置为测试并且没有其他设置,那么测试编译输出显然会使用依赖项。这并不意味着它会被“包含”在任何东西中,只要你不明确地在任何输出中包含依赖项(例如,“package”阶段的输出)。 - Erwan Queffélec
我真的不知道是哪个阶段,我完全是新手使用Maven,有人在IRC频道里让我感到困惑,我怀疑他们是错的,我搜索了一下但没有结果,所以我在stackoverflow上提问。 - Ryan Leach
2个回答

8
简短版:默认情况下,Maven输出(在默认的target目录中)除了当前项目/模块的编译代码外,不包括任何来自依赖项的内容。
稍长版:使用默认的jar打包和没有自定义阶段配置,在Java项目上,Maven的行为如下:
1. compile 阶段:将src/main/java/目录中的.java文件编译成.classes文件,并下载compile范围的依赖项到本地存储库。 2. package 阶段:与第1步相同,同时您将在target目录中获得一个jar文件。 3. install 阶段:与第2步相同,您将在本地存储库中获得一个jar文件。
因此,默认情况下,不会包括任何来自依赖项的.jar文件!
那么,如何在“输出”中包含依赖项,这些作用域是什么意思?
例如,使用assembly插件将依赖项包含在package阶段的输出中(请参见在Maven中将依赖项包含在jar中),通常会获得以下默认行为:
- provided:不包括。 - compile(默认):包括。 - system:不包括。 - runtime:包括。 - test:不包括。
请查看此链接以供参考。
编辑:只需尝试使用不同的作用域值在guice上运行此pom文件,您将看到当作用域为compileruntime时,依赖项包括在fake-1.0-SNAPSHOT-jar-with-dependencies.jar中(此示例不需要任何源文件)。
<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>com.linagora</groupId>
    <artifactId>fake</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>fake</name>
    <dependencies>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>2.0</version>
            <scope>compile</scope>
            <!-- system scope needs 'systemPath' attribute as well
                <systemPath>/path/to/guice/guice-3.0.jar</systemPath>
                <scope>system</scope>
            -->
            <!-- <scope>runtime</scope> -->
            <!-- <scope>test</scope> -->
            <!-- <scope>provided</scope> -->

        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

有人声称编译不会将依赖项包含在组装输出中,以[worldguard]{https://github.com/sk89q/worldguard/blob/master/src/main/assembly/default.xml}为例,它的[pom]{https://github.com/sk89q/worldguard/blob/master/pom.xml}是否执行了非默认操作? - Ryan Leach
你可以通过上面的pom.file看到“default”的内容。只需使用编译范围解压fake-1.0-SNAPSHOT-jar-with-dependencies.jar,就可以看到包含guice文件。 - Erwan Queffélec
1
看了你的例子。他们没有使用“jar-with-dependencies”的配置,所以它不是“与我的相同默认值”。总装本身在Maven中不是默认值,而是一个插件,具有自定义配置,因此当您已经覆盖默认值时,很难分辨什么是“默认值”和什么不是!我使用了jar-with-dependencies总装来说明依赖项scope的影响,现在你懂了... - Erwan Queffélec

3
这不是Maven的工作方式。依赖项只指定类路径(用于编译,运行时,测试)。但默认情况下,依赖项不包含在输出中。您将不得不发送所有依赖项jar文件(至少具有范围编译和运行时)。
请查看依赖项插件。它提供了复制依赖项的目标。
要创建用于发货的包,请查看汇编插件(例如,创建zip文件)。如果这是您想要的内容,它甚至提供了创建全功能jar的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接