Сборка Maven в многомодульном проекте со специальной структурой

Я новичок в Maven, и я думаю, что начал понимать, как это работает. Но я не могу понять плагин сборки maven. Чего я хочу добиться, так это:

Когда все проекты упакованы с соответствующими зависимостями, я хочу, чтобы все они находились в целевом каталоге. Я не хочу, чтобы они были упакованы в одну супер-баночку, потому что система основана на модулях.

Поясню, у меня есть основной проект, сервер, в проекте maven "common", и у меня есть два модуля: "ядро" и "андроид". В общей папке есть также папка conf, которую я хочу скопировать. Я хочу эту структуру:

  • цель /common.jar
  • target/conf/(файлы конфигурации)
  • цель/модули/core.jar
  • цель/модули/android.jar

Структура моего проекта такова:

  • pom.xml (родительский проект)
  • общий/ (модуль maven)
  • ядро/ (модуль maven)
  • android/(модуль maven)

Спасибо за любую помощь или указатели в правильном направлении. :)

EDIT Вот файл сборки ant, который работает на 100%, может быть, мне следует оставить его?

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


person Aldrian    schedule 28.05.2012    source источник
comment
target — это просто рабочий каталог, в котором выполняются сборки. Тебе должно быть все равно, как это выглядит. Я думаю, что вы хотите создать распространяемый архив с плагином сборки, в котором есть соответствующие файлы jar и файлы конфигурации. Это правильно?   -  person Ryan Stewart    schedule 28.05.2012
comment
Райан, это действительно звучит правильно. Вопрос в том, как добиться нужного мне эффекта. Есть несколько советов, которым я мог бы следовать, например, чтобы поместить банки в нужные папки и скопировать папку?   -  person Aldrian    schedule 29.05.2012
comment
@Aldrian. Если вы знаете, как это сделать, у меня есть вопрос: stackoverflow.com/q/33088454/1735836   -  person Patricia    schedule 12.10.2015


Ответы (3)


Во-первых, что делает подключаемый модуль сборки: он упрощает создание tar- или zip-архива, содержащего артефакт(ы), зависимости и другие связанные файлы проекта Maven.

Похоже, все, что вам нужно сделать, это настроить подключаемый модуль сборки с настраиваемым дескриптором для извлечения интересующих вас jar-файлов и файлов конфигурации. Если у вас есть один модуль, который представляет собой «распространяемый» объект — даже если этот модуль зависит от других модулей — тогда вы, вероятно, просто добавьте к нему дескриптор сборки, который включает некоторые файлы, наборы файлов и/или наборы зависимостей.

Если в вашем проекте есть несколько модулей, которые вы хотите включить, и нет ничего, что зависело бы от них всех, вам следует взглянуть на наборы модулей. Мне никогда не приходилось их использовать, но они как раз для этой проблемы.

person Ryan Stewart    schedule 29.05.2012
comment
Райан. Если вы знаете, как это сделать, у меня есть вопрос: stackoverflow.com/q/33088454/1735836 - person Patricia; 12.10.2015

Эта установка решит это именно так, как вы этого хотите.

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 вы можете изменить поведение в соответствии с вашими потребностями.

Если вы хотите упаковать все это в какую-нибудь убер-банку, то вы вольны это сделать.


Изменить:

Хорошо, после прочтения ваших комментариев и просмотра вашего сценария сборки 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.

person maba    schedule 29.05.2012
comment
Прежде всего, спасибо за вашу помощь! В то время как ближе, это непреднамеренно не решило дело. Когда я добавлял зависимости в родительский проект, проект жаловался из-за циклических зависимостей. Core и Android зависят от общего. И у меня есть большинство зависимостей, определенных в основном проекте pom. - person Aldrian; 29.05.2012
comment
@Aldrian Вы хотите, чтобы android.jar и core.jar оказались в common/target, но common.jar имеет зависимости как от android.jar, так и от core.jar? Хорошо, тогда у вас есть проблема. Однако наличие зависимостей, определенных в основном pom.xml, обычно не является проблемой. Я думаю, что вам нужно пересмотреть свою модель. В качестве альтернативы можно было бы иметь четвертый модуль с именем, например. deployment, который разрешит все остальные зависимости. - person maba; 29.05.2012
comment
Ну, common.jar не зависит от android.jar и core.jar, но android.jar и core.jar зависят от common.jar, да, я думаю, мне понадобится четвертая модель, у меня есть временное решение с сценарий сборки Ant, который я опубликую, так как он может помочь выяснить, как полностью сделать это в maven. - person Aldrian; 29.05.2012

Maven по умолчанию использует следующую структуру при сборке для вашего проекта:

  • общий/целевой/общий-.jar
  • ядро/цель/ядро-.jar
  • Android/цель/android-.jar

Однако не все потеряно! Как и в случае с большинством опций в maven, это можно легко перезаписать с помощью соответствующих тегов конфигурации. В вашем случае вы хотите установить тег outputDirectory под своим тегом (в каждом модуле POMS) в соответствующий каталог.

Например, ваш ${basedir}/common/pom.xml должен быть отредактирован, чтобы добавить эту строку:

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


Ваш ./android/pom.xml будет отредактирован аналогичным образом:

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

Я не уверен, что это лучший способ скопировать файлы конфигурации. Вы можете попытаться найти (или написать, так как это довольно простая операция) плагин, чтобы просто копировать файлы и дать ему область действия, такую ​​как «компилировать», указывая при этом на правильный каталог.

person matt5784    schedule 28.05.2012
comment
Спасибо, но это непреднамеренно не сделало того, что я ожидал. Установив выходной каталог сборки, единственное, что произошло, это то, что мои скомпилированные файлы классов были перемещены, а также ресурсы. Если я выполню пакет maven, банки все равно будут в целевой папке для соответствующего модуля:/ - person Aldrian; 29.05.2012
comment
Вы правы, конечно. Я думаю, что тег outputDirectory должен находиться под тегом ‹configuration› внутри плагина maven-compiler-plugin, а-ля ‹plugins› ‹plugin› ‹groupId›org.apache.maven.plugins‹/groupId› ‹artifactId›maven-compiler -plugin‹/artifactId› ‹version›2.5‹/version› ‹configuration› ‹outputDirectory›../target‹/outputDirectory› ‹/configuration› - person matt5784; 29.05.2012