Maven:如何创建没有传播deps的项目?

时间:2014-01-30 09:18:06

标签: java maven

我有一个projectX,它生成一个TXT文件作为其工件。这是该项目产生的唯一工件。这很好用。没问题。

问题是依赖于这个工件的项目会带来所有projectX的工件,这些工件显然不相关,因为TXT文件没有依赖关系。为了生成TXT文件,projectX当然有许多依赖项,但这些与下游项目无关。

我知道我可以在每个使用此TXT文件的单个项目中排除那些传递依赖项。这不是我想要的。我希望它们在projectX中被停止,这样我就不需要在每个下游项目中声明这样的排除。

在我有限的Maven知识中,我想我需要查看projectX依赖项的scope参数。我正在寻找一种范围类型,它说:“这种依赖关系是编译和执行projectX所必需的,但它不是传递的”。找不到这样的范围。

如何在不搞乱下游项目的情况下解决这个问题? (使用projectX生成的工件的那些)

EDIT1 :我对“提供”范围的问题是projectX是以这样的方式制作的,以便它实际上作为构建过程的一部分执行。不可否认,这是不寻常的,但这是产生TXT文件的原因,它是构建的真正输出。换句话说:projectX的依赖项不仅需要用于projectX的编译,还需要用于projectX的执行,但它们不能传播。

EDIT2

我如何执行projectX本身作为其自己的构建过程的一部分:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <id>build-txt-file</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>${java.home}/bin/java</executable>
                <arguments>
                    <argument>-classpath</argument>
                    <!-- automatically creates the classpath using all project dependencies, also adding the project build directory -->
                    <classpath/>
                    <argument>...</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

如果我将projectX的deps声明为provided,则上述步骤将无效。

2 个答案:

答案 0 :(得分:2)

provided范围似乎符合您的要求。引用您链接的Maven文档:

  

这很像编译,但表示您希望JDK或容器在运行时提供依赖。[...]此范围仅在编译和测试类路径上可用,并且不具有传递性。

(强调我的)


编辑(在评论和编辑中澄清之后):回顾一下,似乎Maven意义上的工件不是真正的TXT文件,至少不是唯一的,并且构建实际上编译了一些类并运行它们构建中。 现在,回到解决问题:)。

你被卡住的原因是你可以说是破坏了Maven对工件的约定。具体来说,您的项目的依赖关系期望您的“TXT”项目是其他东西,这就是您遇到问题的原因。

我看到了两种方法:

  • 正如您在评论中提到的,您可以编写一个处理TXT文件生成的插件。
  • 作为一种快速而肮脏的解决方案,您可以:
    1. 将项目拆分为两个:“生成器”(需要deps)和“holder”(仅生成并存储TXT文件)。
    2. 在“生成器”项目中,使用assembly plugin(显然已弃用)或shade plugin(请参阅“示例”)将生成器代码及其所有依赖项打包为“uberjar”。注意指定主类。
    3. 运行install以在您的仓库中包含“生成器”工件。
    4. 在“持有人”项目中,使用dependency plugin将“生成器”JAR复制到target
    5. 最后,在您的“持有人”项目中,使用exec-maven-plugin执行下载的“生成器”JAR。

请注意,第二个解决方案基本上是“穷人的插件”,所以如果你的构建中有更多这样的场景,那么学习编写Mojos可能会在长期内提供更好的收益。不过,我希望这能解决你的问题。

答案 1 :(得分:0)

您应该将“ProjectX”中的依赖项标记为optional。这样,当您的其他项目包含它时,它不会作为传递依赖项解析。 :)

范围“提供”使用由其他东西提供的语义(例如,JEE容器提供 servlet api)。