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

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

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

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

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

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

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

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

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


person David    schedule 30.04.2009    source источник
comment
Вы указали A и B как модули мастера?   -  person millimoose    schedule 30.04.2009
comment
Кроме того, можете ли вы опубликовать, как вы указываете создавать только один модуль через профиль в родительском POM?   -  person millimoose    schedule 30.04.2009
comment
Нет, я не указывал и то, и другое --- в этом суть --- я утверждаю, что было достаточно указать B, а затем maven, глядя на POM для B, должен сам выяснить, что это сначала нужно построить A.   -  person David    schedule 01.05.2009
comment
Я не спрашивал, указали ли вы создание как A, так и B, просто если A является модулем родительского проекта, используя элемент ‹module›. Если вы этого не сделали, Maven не может знать, что A существует. Он работает с использованием логических идентификаторов артефактов, а не соглашений о компоновке модулей, а элементы ‹module› - это способ указать ему, где искать те, которые отсутствуют в репозитории.   -  person millimoose    schedule 01.05.2009
comment
Главный POM знает о B, в частности, я вставил (например) B как модуль в корневой POM. Я это понимаю. Исходя из этого, Maven достаточно умен, чтобы понять, что в подпапке под ним находится проект B. Он идет туда и находит POM для B, который содержит зависимость от чего-то, называемого A. Почему maven сейчас не может виртуально (т.е. только на время выполнения) добавить A в качестве модуля для того же профиля и, следовательно, уйти и построить Первый?   -  person David    schedule 01.05.2009
comment
Если у вас есть главный мастер артефакта: master: 1.0-SNAPSHOT в C: \ work \ master, в Maven нет абсолютно ничего, требующего, чтобы его дочерний модуль master: A: 1.0-SNAPSHOT располагался в C: \ work \ master \ A . Зависимости разрешаются с использованием идентификаторов артефактов, а не имен каталогов. В мастере: B: 1.0-SNAPSHOT вы объявляете зависимость от мастера артефактов: A: 1.0-SNAPSHOT. Если вы не добавите объявление ‹module› для каталога, в котором находится A, Maven не сможет знать, что ему следует искать в этом каталоге pom.xml.   -  person millimoose    schedule 01.05.2009


Ответы (6)


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

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

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

person Rich Seller    schedule 03.07.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>

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

person millimoose    schedule 30.04.2009
comment
Ясно, что это не обязательно. НО, поскольку он начал работать в родительской папке, И у него есть ссылка на модуль, который он может найти в дочерней папке, И он знает всех дочерних элементов под ним, он должен быть в состоянии выяснить для себя, что если есть зависимость от другой модуль, то МОЖЕТ БЫТЬ, он должен поискать его. По крайней мере, это должен быть вариант - кажется, очень разумно хотеть иметь возможность. В противном случае у нас есть этот невероятно сложный инструмент, который может делать всевозможные сложные вещи, но не может справиться с основами! - person David; 01.05.2009
comment
Мне никогда не нужно было создавать только один модуль проекта + его зависимости, в отличие от простого создания всего этого - очевидно, что основы и разумное желание - это субъективно. Если вы спрашиваете, как создать свой проект, вы ответили. Если вы хотите узнать причину этого, я предлагаю связаться с командой Maven. Если вы хотите его изменить, я предлагаю отчет об ошибке. Если вы просто хотите разбить Maven ... - person millimoose; 01.05.2009
comment
Я не пытаюсь обидеть Maven - я думал, что задаю разумный вопрос. Транзитивная зависимость означает, что зависимости не должны определяться глобально. Даже если вы создаете весь проект, я все равно буду утверждать, что Maven ДОЛЖЕН иметь возможность выяснять зависимости модулей, глядя на отдельные POM. Я могу использовать его таким, какой он есть ... Я не прошу помощи --- Я просто (честно) удивлен, что у него нет такой способности, и на самом деле причина, по которой я разместил здесь, была с надеждой что, возможно, был вариант, о котором я не знал, который позволил бы мне это сделать. - person David; 01.05.2009
comment
Глобально определены не зависимости. Где еще, кроме репозиториев, Maven должен искать их при сборке. Если бы вы сначала установили A в свой локальный репозиторий, а затем попытались построить B, это сработало бы. Просто, когда вы хотите, чтобы Maven разрешил дерево зависимостей в большом проекте или перестроил с ним зависимости модуля, вы должны построить их все в одном цикле. - person millimoose; 01.05.2009
comment
Спасибо --- я понимаю, как себя ведет Maven. Мой комментарий действительно о том, как Maven ДОЛЖЕН себя вести. Механизм, который сообщает Maven, что на самом деле он должен искать проекты в дочерних папках, был бы (кажется) чрезвычайно ценным. - person David; 08.05.2009
comment
@Inerdial есть ли где-нибудь пример, который показывает, как реализовать зависимости модуля, как вы показали в своем примере? - person ziggy; 17.02.2012
comment
@ziggy Боюсь, я не совсем понимаю вопрос. Мой пример уже включает большую часть конфигурации, необходимой для реализации обоих макетов, которые я описываю. Если вам нужна помощь в настройке проекта Maven определенным образом, вы должны опубликовать его как отдельный вопрос, этот ответ не предназначен для использования в качестве руководства по макетам модулей Maven. - person millimoose; 18.02.2012

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

person deterb    schedule 14.07.2009
comment
Плагин реактора Maven больше не используется. Он больше не поддерживается. - person Maxim Kornilov; 08.10.2015

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

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

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

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

person mmuller    schedule 13.10.2011

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

person Tomer    schedule 18.05.2015
comment
Как работает этот флажок? Могу ли я получить такое поведение, не запуская Maven из IntelliJ? - person phant0m; 08.03.2017

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

person T Rob Darrough    schedule 19.02.2013