Maven assembly on multi module project with special structure

久未见 提交于 2019-12-06 05:03:07

问题


I'm new to Maven, and I think I've started to get the idea of how it works. But I'm not able to understand the maven assembly plugin. What I want to achieve is this:

When all projects has been packaged, with their respective dependencies, I want to have them all in the target directory. I don't want them to be packaged into one super-jar because the system is based on modules.

Let me explain, I have a main project, the server, in the maven project "common", and I have two modules, "core" and "android". In the common folder, there is also a conf folder that I want copied over. I want this structure:

  • target/common.jar
  • target/conf/(configuration files)
  • target/modules/core.jar
  • target/modules/android.jar

My project structure is this:

  • pom.xml (parent project)
  • common/ (maven module)
  • core/ (maven module)
  • android/ (maven module)

Thank you for any help, or pointers in the right way. :)

EDIT Here is the ant build file which works 100%, maybe I should keep with that?

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


回答1:


First, what the assembly plugin does: it makes it really easy to make a tar or zip archive containing a Maven project's artifact(s), dependencies, and other related files.

It sounds like all you need to do is set up the assembly plugin with a custom descriptor to pull in the jars and config files you're interested in. If you have a single module that represents a "distributable" thing--even if that module depends on other modules--then you'd probably just add an assembly descriptor to it that includes some files, fileSets, and/or dependencySets.

If there are several modules in your project that you want to include and there's nothing that depends on all of them, then you'd want to look at moduleSets. I've never had to use those myself, but they're for exactly that problem.




回答2:


This setup will solve it exactly as you want it.

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>

This last pom is where you can change behavior according to your needs.

If you want to pack all this in some uber-jar then you are free to do so.


Edit:

Ok, after reading your comments and looking at your Ant build script I have come up to the following design/setup that would give you more or less what you want.

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

This assembly descriptor will package your conf files in a separate jar and any project will be able to have a dependency on it.

<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

The dist module will unpack the conf dependency and copy the other dependencies to your target directory.

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

I tend to like working with the maven-dependency-plugin and I find it quite powerful.

The dist module will have all the necessary dependencies to the other modules and download and unpack as you wish. If you then would like to have it all packed in a zip or tar.gz or some other format then you could use the maven-assembly-plugin for that.




回答3:


Maven will default to the following structure when building for your project:

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

However, all is not lost! As with most options in maven, this can easily be overwritten using the proper configuration tags. In your case, you want to set the outputDirectory tag under your tag (in each of the module POMS) to the proper directory.

For example, your ${basedir}/common/pom.xml should be edited to add this line:

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


Your ./android/pom.xml would be edited similarly:

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

I'm not sure the best way to copy over the configuration files. You may want to try to find (or write, since it is a fairly simple operation) a plugin to simply copy files over and give it a scope such as "compile" while pointing it at the proper directory.



来源:https://stackoverflow.com/questions/10787101/maven-assembly-on-multi-module-project-with-special-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!