Maven и зависимые модули
Коллеги рассказывали о чудесах Maven и его магических способностях к зависимости, но я обнаружил, что они терпят неудачу при том, что я считаю очевидным применением.
Предположим, у меня есть корневая папка с основным POM.
Тогда под мной есть несколько проектов, назовите их A и B
B требует A, поэтому POM в папке B содержит соответствующую запись зависимости
Теперь, вернувшись в корневую папку, в профиле я указываю, что хочу собрать B.
Когда я выполняю обычную чистую установку mvn, я получаю ошибку, потому что A не был собран.
Мои друзья говорят мне, что я должен указать и A, и B в этом основном профиле в корне.
Но разве не весь смысл управления зависимостями, который maven видит B, переходит к файлу B POM, где он видит зависимость от A, и поэтому он должен автоматически собирать A.
6 ответов
Причина, по которой я могу думать, что ваше желаемое поведение не было реализовано, заключается в следующем:
Предположим, я работаю над обоими проектами A и B. В настоящее время A не работает. Если бы разрешение зависимостей произошло так, как вам хотелось бы, я бы никогда не смог построить B, пока A не будет исправлен. Поэтому я должен либо откатить свои изменения до A, либо сосредоточиться на исправлении A в первую очередь. В любом случае, возможно, не то, на чем я хочу сосредоточиться прямо сейчас.
Обычно B хочет работать с "последней хорошей" версией A, а не с последней. Использование зависимостей из репозитория означает, что они, по крайней мере, скомпилированы нормально (и, надеюсь, модульные тесты тоже были запущены).
С мастером ПОМ:
~/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, что это местоположения файловой системы, где нужно искать другие артефакты, связанные с этой сборкой.
Взгляните на плагин реактора Maven, в частности на реактор:make, который собирает модуль и все модули, от которых он зависит.
Рич абсолютно прав. То, что вы описываете, обычно не является ожидаемым поведением. Хотя, как заявляет определитель, реактор Maven поддерживает частичные сборки, если модули известны родительскому POM.
Здание с mvn install -pl B -am
должен также сделать (-am
) Зависимости B (то есть A).
В любом случае, модуль A должен быть модулем родительского POM.
Если вы работаете с IntelliJ, у них есть небольшой волшебный флажок: "Разрешить артефакты рабочей области" в их конфигурации запуска Maven. Так что не нужно ни устанавливать, ни строить из родительского.
Ответ в том, что Maven работает не так. Идея Maven состоит в том, чтобы дать разработчику простую и понятную систему управления зависимостями. Получение зависимостей из хранилища является ключом к этому. Каждое исключение ослабляет этот контроль и простоту. Добавление A в качестве зависимости в родительском POM полностью решает ваш сценарий без добавления дополнительных исключений. Использование пакетных файлов или скриптов ant - это еще один способ решения вашего сценария.