【问题标题】:Maven assembly on multi module project with special structure具有特殊结构的多模块项目的Maven组装
【发布时间】:2012-05-28 15:34:00
【问题描述】:

我是 Maven 新手,我想我已经开始了解它的工作原理了。但我无法理解 maven 程序集插件。我想要实现的是:

当所有项目都打包后,以及它们各自的依赖项,我想将它们全部放在目标目录中。我不希望它们被打包到一个超级 jar 中,因为系统是基于模块的。

让我解释一下,我有一个主项目,服务器,在 maven 项目“common”中,我有两个模块,“core”和“android”。在 common 文件夹中,还有一个我想要复制的 conf 文件夹。我想要这个结构:

  • target/common.jar
  • target/conf/(配置文件)
  • target/modules/core.jar
  • target/modules/android.jar

我的项目结构是这样的:

  • pom.xml(父项目)
  • common/(maven 模块)
  • 核心/(maven 模块)
  • android/(maven 模块)

感谢您的任何帮助,或以正确的方式提供指导。 :)

编辑这是 100% 工作的 ant 构建文件,也许我应该保留它?

<target name="init">
    <mkdir dir="dist" />
    <mkdir dir="dist/conf/" />
    <mkdir dir="dist/modules/" />
    <mkdir dir="dist/libs/" />

    <copy includeemptydirs="false" todir="dist/conf">
        <fileset dir="common/conf" />
    </copy>
</target>

<target name="copy-server">
    <copy todir="dist">
        <fileset file="common/target/server*.jar" />
    </copy>
</target>

<target name="copy-modules">
    <copy todir="dist/modules/">
        <fileset file="core/target/*.jar" />
        <fileset file="android/target/*.jar" />
    </copy>
</target>

<target name="copy-libs">
    <copy todir="dist/libs">
        <fileset dir="common/target/libs" />
        <fileset dir="core/target/libs" />
        <fileset dir="android/target/libs" />
    </copy>
    <delete>
        <fileset file="dist/libs/server*.jar" />
    </delete>
</target>

<target name="clean">
    <delete dir="dist" />
</target>

<target name="full-build" depends="clean, init, copy-server, copy-libs, copy-modules, increment">
    <echo message="Copying the fully built Maven project" />
</target>

<target name="increment">
    <propertyfile file="common/conf/version.properties">
        <entry key="build.number" type="int" operation="+" default="0" />
    </propertyfile>
    <property file="common/conf/version.properties" />
    <echo message="Build number is ${build.number}"/>
</target>

【问题讨论】:

  • target 只是一个执行构建的工作目录。你不应该关心那是什么样子。我认为您想要的是使用包含适当 jar 和配置文件的程序集插件构建可分发的存档。对吗?
  • Ryan,这听起来确实正确。问题是如何达到我想要的效果。有一些我可以遵循的指示,比如将罐子放入我想要的文件夹中,然后复制文件夹?
  • @Aldrian - 如果你知道怎么做,我在这里有个问题:stackoverflow.com/q/33088454/1735836

标签: maven maven-assembly-plugin multi-module


【解决方案1】:

首先,程序集插件的作用:它使制作包含 Maven 项目的工件、依赖项和其他相关文件的 tar 或 zip 存档变得非常容易。

听起来您需要做的就是 set up the assembly plugin 使用自定义描述符来拉入您感兴趣的 jars 和配置文件。如果您有一个代表“可分发”事物的模块 - 即使该模块依赖于其他模块——那么您可能只需向其中添加一个 assembly descriptor,其中包括一些 filesfileSets 和/或 dependencySets

如果您的项目中有多个模块需要包含并且没有任何依赖于所有模块,那么您需要查看moduleSets。我自己从来没有使用过这些,但它们正是为了解决这个问题。

【讨论】:

【解决方案2】:

此设置将完全按照您的要求解决。

directory layout

+- pom.xml
+- android
| +- pom.xml
| +- src
|   +- main
|     +- java
+- core
| +- pom.xml
| +- src
|   +- main
|     +- java
+- common
  +- pom.xml
  +- src
    +- main
     +- java
     +- resources
       +- conf

pom.xml

<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.example</groupId>
    <artifactId>my-project</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>

    <name>${project.artifactId}-${project.version}</name>

    <modules>
        <module>android</module>
        <module>common</module>
        <module>core</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>core</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>android</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

android/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>android</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

</project>

core/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>core</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

</project>

common/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>common</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>android</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <targetPath>${project.build.directory}</targetPath>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <stripVersion>true</stripVersion>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

最后一个 pom 是您可以根据需要更改行为的地方。

如果您想将所有这些打包到某个 uber-jar 中,那么您可以随意这样做。


编辑

好的,在阅读了您的 cmets 并查看了您的 Ant 构建脚本之后,我提出了以下设计/设置,它或多或少可以满足您的需求。

directory layout

+- pom.xml
+- android
| +- pom.xml
| +- src
|   +- main
|     +- java
+- core
| +- pom.xml
| +- src
|   +- main
|     +- java
+- common
| +- pom.xml
| +- conf.xml
| +- src
|   +- main
|    +- java
|    +- resources
|      +- conf
+- dist
  +- pom.xml

pom.xml

<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.example</groupId>
    <artifactId>my-project</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0-SNAPSHOT</version>

    <name>${project.artifactId}-${project.version}</name>

    <modules>
        <module>android</module>
        <module>common</module>
        <module>core</module>
        <module>dist</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>common</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>common</artifactId>
                <version>${project.version}</version>
                <classifier>conf</classifier>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>core</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>android</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

android/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>android</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
        </dependency>
    </dependencies>
</project>

core/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>core</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
        </dependency>
    </dependencies>
</project>

common/pom.xml

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>common</artifactId>
    <packaging>jar</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>conf.xml</descriptor>
                            </descriptors>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

common/conf.xml

这个程序集描述符会将你的 conf 文件打包到一个单独的 jar 中,任何项目都可以依赖它。

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>conf</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${basedir}/src/main/resources/conf</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>*.properties</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

dist/pom.xml

dist 模块将解压 conf 依赖并将其他依赖复制到你的目标目录。

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

    <parent>
        <groupId>com.example</groupId>
        <artifactId>my-project</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>dist</artifactId>
    <packaging>pom</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>common</artifactId>
            <classifier>conf</classifier>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>android</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>core</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>modules</id>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.example</groupId>
                                    <artifactId>android</artifactId>
                                </artifactItem>
                                <artifactItem>
                                    <groupId>com.example</groupId>
                                    <artifactId>core</artifactId>
                                </artifactItem>
                                <artifactItem>
                                    <groupId>com.example</groupId>
                                    <artifactId>common</artifactId>
                                    <outputDirectory>${project.build.directory}</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <stripVersion>true</stripVersion>
                        </configuration>
                    </execution>
                    <execution>
                        <id>unpack</id>
                        <phase>package</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.example</groupId>
                                    <artifactId>common</artifactId>
                                    <classifier>conf</classifier>
                                </artifactItem>
                            </artifactItems>
                            <excludes>**/MANIFEST.MF</excludes>
                            <outputDirectory>${project.build.directory}</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我倾向于喜欢使用maven-dependency-plugin,我发现它非常强大。

dist 模块将具有对其他模块的所有必要依赖项,并根据需要下载和解压缩。如果您希望将其全部打包成 zip 或 tar.gz 或其他格式,那么您可以使用 maven-assembly-plugin

【讨论】:

  • 首先感谢您的帮助!虽然更近了,但这并没有解决这个问题。当我在父项目中添加依赖项时,由于循环依赖项,该项目正在抱怨。 Core和Android都依赖共同点。而且我在主项目 pom 中定义了大部分依赖项。
  • @Aldrian 您希望android.jarcore.jarcommon/target 结尾,但common.jarandroid.jarcore.jar 都有依赖关系?好的,那你就有问题了。不过,在主 pom.xml 中定义依赖项通常不是问题。我认为你必须重新考虑你的模型。另一种方法是使用第四个模块,例如deployment 将解决所有其他依赖项。
  • 嗯,common.jar 不依赖于 android.jar 和 core.jar,但是 android.jar 和 core.jar 依赖于 common.jar ,是的,我想我需要第四个模型,我现在有一个使用 Ant 构建脚本的临时解决方案,将发布它,因为它可能有助于弄清楚如何在 maven 中完全做到这一点。
【解决方案3】:

为您的项目构建时,Maven 将默认采用以下结构:

  • common/target/common-.jar
  • core/target/core-.jar
  • android/target/android-.jar

但是,一切都没有丢失!与 maven 中的大多数选项一样,这可以使用适当的配置标签轻松覆盖。在您的情况下,您希望将标签下的 outputDirectory 标签(在每个模块 POMS 中)设置为正确的目录。

例如,应编辑您的 ${basedir}/common/pom.xml 以添加此行:

...
<build>
    <outputDirectory>../target</outputDirectory>
...


您的 ./android/pom.xml 将被类似地编辑:

...
<build>
    <outputDirectory>../target/modules</outputDirectory>
...

我不确定复制配置文件的最佳方式。您可能想尝试查找(或编写,因为它是一个相当简单的操作)一个插件来简单地复制文件并给它一个范围,例如“编译”,同时将其指向正确的目录。

【讨论】:

  • 谢谢,但这并不符合我的预期。通过设置构建输出目录,唯一发生的事情就是我编译的类文件以及资源被移动了。如果我执行 maven 包,jar 仍将位于相应模块的目标文件夹中:/
  • 你是对的,当然。我认为 outputDirectory 标签需要在 maven-compiler-plugin 内的 标签下,例如 org.apache.maven.pluginsmaven-compiler -plugin2.5../target
猜你喜欢
  • 1970-01-01
  • 2012-03-12
  • 2014-03-08
  • 2016-12-12
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 2011-02-11
相关资源
最近更新 更多