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

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

48 голосов
/ 30 апреля 2009

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

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

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

.

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

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

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

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

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

Ответы [ 6 ]

40 голосов
/ 30 апреля 2009

С мастером ПОМ:

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

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

25 голосов
/ 03 июля 2009

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

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

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

14 голосов
/ 14 июля 2009

Взгляните на плагин для реактора Maven , в частности на реактор: make, который собирает модуль и все модули, от которых он зависит.

5 голосов
/ 13 октября 2011

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

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

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

(см. Модули Maven + Построение отдельного специального модуля )

4 голосов
/ 18 мая 2015

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

3 голосов
/ 19 февраля 2013

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

...