Maven зависимость без версии
Недавно я работал над некоторыми улучшениями в проекте, разработанном некоторое время назад, и вот что я нашел. Множество зависимостей в pom-файлах не имеют указанных версий, но они разрешены. Проект состоит из 1 корневого модуля и 2 подмодулей. Используется шаблон Aggregator, что означает, что в нем вообще отсутствует раздел dependencyManagement. Верхний проект просто объединяет 2 модуля, и это все, что он делает. Подпроекты не относятся к нему как к родителю. У них другой родитель. Чего я не могу понять, так это того, что ни сами подпроекты, ни их родительские объекты (на самом деле, они также не имеют зависимостей) не определяют версии для некоторых зависимостей. Например:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>imap</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
Может кто-нибудь помочь мне понять это? Maven обрабатывает управление версиями по какой-то стратегии по умолчанию? Что это за стратегия по умолчанию?
5 ответов
Ладно, думаю, я сам на это отвечу. Конечно, я взглянул на зависимости: дерево, но все зависимости, которые я упомянул, были членами дерева первого уровня. То, что я не сразу заметил, это то, что dependencyManagement
отсутствует в родительском элементе, но, тем не менее, присутствует в подмодулях, и, что более интересно, он содержит:
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.0.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Я никогда не использовал Spring IO Platform раньше, так что это абсолютно новая концепция для меня. Как оказалось, платформа включает в себя довольно много предварительно настроенных зависимостей: http://docs.spring.io/platform/docs/current/reference/htmlsingle/
Maven не может работать без определения версий артефактов. Они должны быть определены где-то в теге dependencyManagement либо в подмодуле, либо в родительском. Пожалуйста, проверьте вашу иерархию пом. использование mvn help:effective-pom
в каталоге подмодулей проекта. Также вы можете использовать mvn dependency:tree
чтобы выяснить, какие артефакты - вместе с полной информацией об артефактах, включая номера версий - разрешаются в результате управления зависимостями.
Использовать
mvn -P<my_profile_of_interest> help:effective-pom -Dverbose
Подробный режим (Начиная с: 3.2.0) добавляет XML-комментарии, содержащие точную ссылку на место, откуда исходит объявление зависимости.
Каждая зависимость maven, определенная в pom, должна иметь версию прямо или косвенно, например, через dependencyManagement или parent. При этом, если версия не указана, то будет использоваться версия, указанная в dependencyManagement или родительском pom.
Например: в приведенном ниже pom (упомянуты только важные разделы) не указана версия для артефакта jstl. Однако в "mvn dependency:tree" показано, что jstl версии 1.2 включен. И если посмотреть на spring-boot-starter-parent, для версии 2.3.3.RELEASE pom он включает jstl версии 1.2.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
....
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
....
</dependencies>
В моем случае, если бы я использовал родитель Spring boot starter для управления всеми зависимостями и
lombok
версия управляется Spring boot. Эта проблема возникла из-за более высокой
java version
ЯВА 11 . Я экспортировал JAVA 8 в свою среду времени компиляции, и после использования JAVA 8 эта проблема исчезла.