将maven组件归档到bundle模块中

时间:2009-07-23 16:58:48

标签: maven-2

我有几个子模块(比如A,B + C),每个模块生成一个程序集tar.gz和一个模块(X),它们将tarball解压缩到目标目录中,将它们捆绑在一起。

现在使用分类器设置我对A,B + C的依赖关系并输入模块X POM并使用带有dependencySets的汇编文件模块似乎没有从我的本地仓库中拉出tarball,而是重建它。

这会导致问题,因为A,B + C都有自己的过滤器。当X重建A时,它会保持未经过滤。我想要maven从我的仓库中获取A-distro.tar.gz,或者如果不存在重建A,将其放入仓库然后让X使用它。

这是我正在使用的assembly.xml文件。使用坐标时,我无法使moduleSets工作,所以:

<assembly>
    <id>distro</id>
    <formats>
        <format>dir</format>
        <format>tar.gz</format>
    </formats>
    <baseDirectory>${project.version}</baseDirectory>
    <includeBaseDirectory>false</includeBaseDirectory>

    <dependencySets>

        <dependencySet>
            <useTransitiveFiltering>true</useTransitiveFiltering>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>false</unpack>
            <outputDirectory>/lib</outputDirectory>
            <excludes>
                <exclude>*:tar.gz</exclude>
            </excludes>
        </dependencySet>

        <dependencySet>
            <useTransitiveFiltering>true</useTransitiveFiltering>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>true</unpack>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*:tar.gz</include>
            </includes>
        </dependencySet>

    </dependencySets>

</assembly>

项目X的POM:

<project>
  <parent>
    <artifactId>parent_project</artifactId>
    <groupId>org.myorg</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.myorg</groupId>
  <artifactId>X</artifactId>
  <packaging>pom</packaging>
  <name>X</name>
  <version>1.0-SNAPSHOT</version>
  <build>
          <plugins>
                <plugin>
                        <artifactId>maven-assembly-plugin</artifactId>
                </plugin>
          </plugins>

    </build>

  <dependencies>
          <dependency>
              <groupId>org.myorg</groupId>
              <artifactId>A</artifactId>
              <classifier>distro</classifier>
              <type>tar.gz</type>
        </dependency>
  </dependencies>
</project>

(RS从OP的回答中移动了内容)

好的,谢谢你的回复。

我使用你描述的原理创建了一个测试项目,其中一个模块用于汇编,一个用于聚合器:

./pom.xml
./bundle
./bundle/pom.xml
./bundle/src
./bundle/src/main
./bundle/src/main/assembly
./bundle/src/main/assembly/assembly-files.xml
./bundle/src/main/assembly/assembly.xml
./module1
./module1/pom.xml
./module1/src
./module1/src/main
./module1/src/main/assembly
./module1/src/main/assembly/assembly-files.xml
./module1/src/main/assembly/assembly.xml
./module1/src/main/conf
./module1/src/main/java
./module1/src/main/java/org
./module1/src/main/java/org/test
./module1/src/main/java/org/test/Test.java
./module2
./module2/pom.xml
./module2/src
./module2/src/main
./module2/src/main/java
./module2/src/main/java/org
./module2/src/main/java/org/test
./module2/src/main/java/org/test/Test.java

模块1生成以下坐标的程序集文件:

        <dependency>
            <groupId>org.test</groupId>
            <artifactId>module1</artifactId>
            <version>1.0-SNAPSHOT</version>
            <classifier>distro</classifier>
            <type>tar.gz</type>
        </dependency>

生成以下文件:

〜/ mvnrepos /组织/测试/模块1 / 1.0-SNAPSHOT / module1-1.0-快照distro.tar.gz

使用以下程序集构建bundle时,tar.gz会被拉入并使用:

<assembly>
    <id>distro</id>
    <formats>
        <format>dir</format>
        <format>tar.gz</format>
    </formats>
    <baseDirectory>${project.version}</baseDirectory>
    <includeBaseDirectory>false</includeBaseDirectory>


    <dependencySets>

        <dependencySet>
            <includes>
                <include>org.test:module1:tar.gz</include>
            </includes>
            <useTransitiveFiltering>true</useTransitiveFiltering>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>true</unpack>
            <unpackOptions>
                <excludes>
                        <exclude>lib/</exclude>
                </excludes>
            </unpackOptions>
            <outputDirectory>lib/</outputDirectory>
        </dependencySet>

    </dependencySets>

<!-- just includes conf and bin dirs -->
    <componentDescriptors>
        <componentDescriptor>src/main/assembly/assembly-files.xml</componentDescriptor>
    </componentDescriptors>

</assembly>

但是,如果我清理我的存储库并清理根目录下的项目,那么tar.gz就会被完全删除,当我更改到bundle目录并且mvn安装它失败,因为maven无法解决它需要重建模块1没有tar.gz才能得到它。这是我的捆绑pom:

<project>
  <parent>
    <artifactId>test_parent</artifactId>
    <groupId>org.test</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test</groupId>
  <artifactId>bundle</artifactId>
  <packaging>pom</packaging>
  <name>bundle</name>
  <version>1.0-SNAPSHOT</version>
  <url>http://maven.apache.org</url>
  <build>
          <plugins>
                <plugin>
                        <artifactId>maven-assembly-plugin</artifactId>
                </plugin>
          </plugins>
    </build>

  <dependencies>

            <dependency>
                <groupId>org.test</groupId>
                <artifactId>module1</artifactId>
            </dependency>

            <dependency>
                <groupId>org.test</groupId>
                <artifactId>module2</artifactId>
            </dependency>

            <dependency>
                <groupId>org.test</groupId>
                <artifactId>module1</artifactId>
                <version>1.0-SNAPSHOT</version>
                <classifier>distro</classifier>
                <type>tar.gz</type>
                <scope>runtime</scope>
            </dependency>

  </dependencies>
</project>

如何让maven意识到必须通过重建模块1来重建程序集?

我正在尝试将每个程序集保存在一个单独的模块中,这样每个模块都可以作为一个单独的单元进行构建和测试,而不是需要重建一个聚合器才能运行任何模块。然后,如果需要完整运行,则可以通过简单地将每个程序集tarball解压缩到bundle / target下的目录来构建bundle。

也许上面的内容正在反对 - 但这似乎是Sonotype一书中maven汇编章节的主旨:

http://www.sonatype.com/books/maven-book/reference/assemblies-sect-assembling-via-depend.html

不幸的是,sonotype提供的示例zip在第12章中没有任何内容: - (

当然,我可以突破蚂蚁并使用它,但是如果可能的话,我希望纯粹在maven中实现。

btw maven-assembly-plugin版本是2.2-beta-2。

2 个答案:

答案 0 :(得分:0)

我不确定我理解你的问题,所以让我试着改写一下。

你有4个项目,A,B,C和X.你有A,B和C被定义为X的子项目 在构建项目X时,您希望包含项目A,B和C的tar.gz文件。

问题是您只想在需要时构建A,并从项目中下载它 存储库,如果它已经存在?

假设我正确理解了这个问题,我仍然不清楚你是如何期望孩子们有条不紊地建造的。如果X将其他模块声明为模块Maven将始终与父模块一起构建它们。如果X将其他参数声明为依赖项,则它们将仅被视为依赖项,因此构建将失败,除非存储库中存在工件(即您已经构建它们)。


如果您希望能够在构建上保持灵活性,我建议将程序集和聚合器的职责分离到不同的项目中。

聚合器只是将项目声明为模块,因此您可以在一个命令中方便地构建所有项目。

汇编项目(您的项目X)声明项目A,B和C的依赖项。当您构建项目X时,需要已经构建了其他项目,但如果在聚合器中构建,则反应器将构建它们第一。然而,如果你独立构建它,你知道其他的是最新的。


关于Maven使用的一些额外要点应该澄清这种方法。

Maven存储库是您开发的所有工件的记录。您不需要清除构建之间的本地存储库。它旨在充当所有工件的存储库。因此,如果您安装项目A,那就是将始终使用的版本(除非您重建项目A)。

如果必须清除本地存储库,则应部署工件到远程存储库(请参阅Nexus book的相关部分以获取指导开始时)即使本地存储库被清除,它们也可以合并到项目X的构建中。

因此,构建项目的工作流程是:

  1. 在聚合器项目或相关项目(A,B或C)上运行mvn install。
  2. 项目已安装到本地存储库。
  3. 不要清除本地存储库!
  4. 在项目X上运行mvn install,Maven将从存储库中检索依赖项并将它们打包到程序集中。
  5. 如果使用mvn deploy,则适用相同的原则,但由于工件位于远程存储库中,因此您可以自由清除本地存储库。

    强调我之前的观点:

    • 没有机制来有条件地构建模块。它们要么构建要么不构建(但是如果不需要构建的某些步骤可能会被跳过,例如编译可能已经在之前的构建中完成)
    • 无需清除本地存储库(如果这样做,您应该将模块部署到远程存储库,以便可以检索它们。)

答案 1 :(得分:0)

好的我应该更清楚我为什么要清理本地仓库 - 我知道这不是构建周期的一部分。

我正在清理我的本地仓库以模仿如果我第一次尝试构建并且远程仓库中没有任何东西会发生什么。这是因为在检查父+模块时,我需要的所有代码都存在。

Parent
\----module1 (includes assembly classifier)
|
\----module2
|
\----bundle

例如,使用来自parentbuilds module1的空repo进行构建,然后使用module2进行捆绑。一切顺利,按顺序排列:

parent,module1,module2,bundle

但是如果我有一个空的repos和cd到X那么构建maven就无法解决它需要构建依赖于module1和module2的父代,所以如果可能的话我希望它按照这个顺序构建:

parent,module1,module2,bundle

我认为这在maven中是不可能的,因为你说没有条件模块构建的机制!我认为maven会支持这个,因为它有关于父母的信息,父母有关于孩子的信息,但我认为我推断太多了。

非常感谢你的回复Rich。与maven一起到达,但这就像拔牙一样,很大程度上归功于超声波手册的风格。

ps编辑问题会丢失上下文。我没有意识到stackoverflow做到了这一点。 usenet风格第一次就是正确的,写下你自己的回复,如果需要,包括对前回复的引用,在底部发布。编辑先前的帖子恕我直言删除了对话的流程 - 对于某些问题,解决方案的旅程与目的地一样具有指导意义!最后一段是400个字符: - )

例如,我无法按照建议放置此评论,因为它超过了600个字符的技术音障。