Maven и зависимые модули

Коллеги рекламировали чудеса maven и его магическую зависимость, но я обнаружил, что это не удается из-за того, что я считаю очевидным.

Предположим, что у меня есть корневая папка с основным ПОМ.

Затем под мной есть несколько проектов, назовите их A и B

B требует A, и поэтому POM в папке B имеет соответствующую запись зависимостей в ней

Теперь, в корневой папке, в профиле, я указываю, что хочу построить B.

Когда я выполняю обычную чистую установку mvn, я получаю сбой, потому что A не был создан.

Мои друзья говорят мне, что я должен указать как A, так и B в этом основном профиле в корне.

Но не вся суть управления зависимостями, что maven видит B, переходит в B POM файл, где видит зависимость от A, и поэтому он должен автоматически строить A.

Ответ 1

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

Предположим, что я работаю над обоими проектами A и B. В настоящее время A сломан. Если разрешение зависимостей произошло так, как вам бы хотелось, я бы никогда не смог построить B до тех пор, пока не будет исправлено A. Поэтому я либо должен отменить мои изменения в A, либо сосредоточиться на фиксации A в первую очередь. В любом случае, возможно, не то, на что я хочу сосредоточиться прямо сейчас.

Обычно B хочет работать с "последней хорошей" версией A, а не последним. Использование зависимостей из репозитория означает, что они, по крайней мере, скомпилированы в порядке (и, надеюсь, модульные тесты также выполнялись).

Ответ 2

С помощью мастера POM:

~/scratch/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>scratch</groupId>
    <artifactId>scratch</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>nipple</module>
        <module>cabbage</module>
    </modules>
</project>

И модуль POMs:

~/scratch/nipple/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>nipple</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

~/scratch/cabbage/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <parent>
        <artifactId>scratch</artifactId>
        <groupId>scratch</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <groupId>scratch</groupId>
    <artifactId>cabbage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>scratch</groupId>
            <artifactId>nipple</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

Я могу выпустить mvn package в корневой каталог после очистки моего локального репозитория и в итоге создать все модули. (В пустые дескрипторы JAR, но построены.)

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

Причина, по которой это так, может быть вызвана тем, что макет каталога, где расположение модулей будет предсказуемым, никоим образом не является обязательным. Это даже несколько распространено и приемлемо, что макет для приведенного выше примера выглядит следующим образом:

projects
|
+--scratch
|  |
|  +--scratch-parent
|  |  |
|  |  +--pom.xml [The POM of scratch:scratch:1.0-SNAPSHOT]
|  |
|  +--nipple
|  |  |
|  |  +--pom.xml [The POM of scratch:mod1:1.0-SNAPSHOT]
|  |
|  +--cabbage
|  |  |
|  |  +--pom.xml [The POM of scratch:mod2:1.0-SNAPSHOT]

В этом случае раздел <modules> родительского POM будет:

<modules>
    <module>../nipple</module>
    <module>../cabbage</module>
</modules>

Обратите внимание, что нет ничего, говоря, какой идентификатор артефакта находится в каком модуле. Он просто служит для указания Maven, что это места файловой системы, где можно искать другие артефакты, связанные с этой сборкой.

Ответ 4

Богатый полностью прав. То, что вы описываете, обычно не является ожидаемым поведением. Хотя, как указано в определении, реактор Maven поддерживает частичные сборки, если модули известны родительской POM.

Строка с mvn install -pl B -am также должна содержать (-am) B зависимости (то есть A).

В любом случае модуль A должен быть модулем родительского POM.

(см. Модули Maven + Создание единого специализированного модуля)

Ответ 5

Если вы работаете с IntelliJ, у них есть небольшой волшебный флажок: "Разрешить артефакты рабочего пространства" в их конфигурации запуска Maven. Поэтому нет необходимости устанавливать и строить из родителя.

Ответ 6

Ответ только в том, что это не то, как работает Maven. Идея Maven заключается в том, чтобы дать разработчику логичную, простую систему для управления зависимостями. Получение зависимостей от хранилища является ключом к этому. Каждое исключение ослабляет этот контроль и простоту. Добавление A как зависимости в родительском POM полностью соответствует вашему сценарию без добавления дополнительных исключений. Использование командных файлов или скриптов ant - это еще один способ решения вашего сценария.