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

Я использую плагин сборки Maven для создания сборки для моего многомодульного проекта. Существует два отдельных приложения, построенных из этого многомодульного проекта, Каждый из которых имеет отдельный набор зависимостей. Я сделал пользовательский дескриптор сборки, который собирает два каталога (для каждого приложения) со сборками модулей и их соответствующими зависимостями. Он делает все хорошо, но одно - он помещает зависимости для обоих модулей в сборку друг друга.

далее упрощенная версия моего проекта, которая имеет точно такое же поведение.

рассмотрим проект, состоящий из двух модулей и сборка модуля:

APP
  module1
  module2
  assembly

я добавил зависимости исключительно для демонстрации:

com.test.app:module1:jar:1.0
- commons-cli:commons-cli:jar:1.2:compile

com.test.app:module2:jar:1.0
- commons-daemon:commons-daemon:jar:1.0.8:compile

вот родительский пом:

<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.test</groupId>
  <artifactId>app</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>

  <modules>
    <module>module1</module>
    <module>module2</module>
    <module>assembly</module>
  </modules>
</project>

модуль1 пом:

<project>
  <parent>
    <groupId>com.test</groupId>
    <artifactId>app</artifactId>
    <version>1.0</version>
  </parent>

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.test.app</groupId>
  <artifactId>module1</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
      <version>1.2</version>
    </dependency>
  </dependencies>
</project>

module2 POM:

<project>
  <parent>
    <groupId>com.test</groupId>
    <artifactId>app</artifactId>
    <version>1.0</version>
  </parent>

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.test.app</groupId>
  <artifactId>module2</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>commons-daemon</groupId>
      <artifactId>commons-daemon</artifactId>
      <version>1.0.8</version>
    </dependency>
  </dependencies>
</project>

сборка POM:

<project>
  <parent>
    <groupId>com.test</groupId>
    <artifactId>app</artifactId>
    <version>1.0</version>
  </parent>

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.test.app</groupId>
  <artifactId>assembly</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2.2</version>

        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>

            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>

        <configuration>
          <appendAssemblyId>false</appendAssemblyId>

          <descriptors>
            <descriptor>src/main/assembly/descriptor.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

и, наконец, сборка дескриптор:

<assembly>
  <id>distribution</id>
  <includeBaseDirectory>false</includeBaseDirectory>

  <formats>
    <format>dir</format>
  </formats>

  <moduleSets>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>

      <includes>
        <include>com.test.app:module1:jar</include>
      </includes>

      <binaries>
        <outputDirectory>module1</outputDirectory>
        <unpack>false</unpack>

        <dependencySets>
          <dependencySet>
            <unpack>false</unpack>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>

    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>

      <includes>
        <include>com.test.app:module2:jar</include>
      </includes>

      <binaries>
        <outputDirectory>module2</outputDirectory>
        <unpack>false</unpack>

        <dependencySets>
          <dependencySet>
            <unpack>false</unpack>
          </dependencySet>
        </dependencySets>
      </binaries>
    </moduleSet>
  </moduleSets>
</assembly>

как вы можете видеть, сборка привязывается к фазе пакета. Итак, когда я выполняю

mvn package

из родительского каталога, у меня есть следующие сборки

module1/
  commons-cli-1.2.jar
  commons-daemon-1.0.8.jar
  module1-1.0.jar
module2/
  commons-cli-1.2.jar
  commons-daemon-1.0.8.jar
  module2-1.0.jar

в принципе, проблема здесь в том, что module1 не зависит от commons-daemon, но плагин сборки включил зависимость. Аналогично, с module2 и commons-cli.

может кто-нибудь объяснить, почему плагин сборка ведет себя таким образом?

что было бы решением?

1 ответов


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

тем не менее, возможным обходом было бы иметь module1 и module2 генерировать свои собственные артефакты сборки, которые содержат их соответствующие банки и зависимости. Затем можно изменить сборку суб-модуль POM-файл, чтобы иметь зависимости от сгенерированных артефактов распределения из его модулей-братьев, а затем распаковать их в новую сборку.

в файлах Pom Module1 и Module2 вы можете добавить конфигурацию плагина сборки в фазу пакета, как и в субмодуле сборки.

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2.2</version>

        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>

        <configuration>
          <descriptors>
            <descriptor>src/main/assembly/descriptor.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
    </plugins>
  </build>

Module1 будет иметь src / main/assembly / descriptor.xml, как это

<assembly>
  <id>distribution</id>
  <includeBaseDirectory>false</includeBaseDirectory>

  <formats>
    <format>zip</format>
  </formats>

  <dependencySets>
    <dependencySet>
      <outputDirectory>module1</outputDirectory>
      <unpack>false</unpack>
    </dependencySet>
  </dependencySets>
</assembly>

и module2 будет похож src / main / assembly / descriptor.в XML

<assembly>
  <id>distribution</id>
  <includeBaseDirectory>false</includeBaseDirectory>

  <formats>
    <format>zip</format>
  </formats>

  <dependencySets>
    <dependencySet>
      <outputDirectory>module2</outputDirectory>
      <unpack>false</unpack>
    </dependencySet>
  </dependencySets>
</assembly>

затем в сборке / pom.xml вы бы добавили модуль 1 и 2 zip артефакты в качестве зависимостей

  <dependencies>
    <dependency>
      <groupId>com.test.app</groupId>
      <artifactId>module1</artifactId>
      <version>1.0</version>
      <type>zip</type>
      <classifier>distribution</classifier>
    </dependency>
    <dependency>
      <groupId>com.test.app</groupId>
      <artifactId>module2</artifactId>
      <version>1.0</version>
      <type>zip</type>
      <classifier>distribution</classifier>
    </dependency>
  </dependencies>

...и обрезать assembly / src / main/assembly / descriptor.xml-файл должен выглядеть так

<assembly>
  <id>distribution</id>
  <includeBaseDirectory>false</includeBaseDirectory>

  <formats>
    <format>dir</format>
  </formats>

  <dependencySets>
    <dependencySet>
      <useTransitiveDependencies>false</useTransitiveDependencies>
      <unpack>true</unpack>
    </dependencySet>
  </dependencySets>

</assembly>

как я уже сказал, это будет одна возможная работа и, к сожалению, добавляет значительное количество дополнительной конфигурации XML в ваш процесс сборки. Но это работает.