#java #maven-3
#ява #мавен #maven
Вопрос:
Я разработал и построил свое Java-приложение, используя Maven. Мне нужно поддерживать Java 1.6, поэтому я использую следующие свойства:
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.6</maven.compiler.source>
Тем не менее, когда я запускаю приложение, я получаю ошибку «Неподдерживаемая основная.второстепенная версия», и я подозреваю, что одна из моих банок зависимостей скомпилирована с версией Java, более новой, чем та, которую мне нужно поддерживать.
Мои вопросы:
-
Возможно ли это вообще? Я думал, что Maven позаботится о такого рода проблемах с версиями зависимостей.
-
Есть ли простой способ узнать младшую / основную версию всех моих зависимостей? (Было бы здорово, если бы это можно было показать, например, при выполнении
mvn dependency:tree
.)
Комментарии:
1. Можете ли вы опубликовать весь свой файл maven?
2. Есть некоторые вещи, которые я бы предпочел не раскрывать на SO, например, информация о сертификате. Но вот урезанная версия соответствующих частей: pastebin.com/BE7yDbSV
3. Похоже, что Jersey 2.6 была последней версией, скомпилированной на java 6. После этого это была java 7. Ссылка: jersey.java.net/documentation/latest /…
4. ОК. Я думаю, что Джексон тоже является проблемой. Я тоже, вероятно, мог бы откопать эту информацию вручную. Однако это не отвечает ни на один из моих двух вопросов.
5. Я нашел, где jackson 2.3 скомпилирован на Java 6. Я не могу найти ничего определенного в 2.4. Что касается ваших вопросов, 1) maven не будет выполнять автоматическое понижение такого рода, вы должны указать это самостоятельно. 2) Я не знаю хорошего способа выяснить зависимости основных и второстепенных версий. Однако это не значит, что его не существует.
Ответ №1:
Проблема в том, что каждая зависимость (сопровождающий) может самостоятельно решить, какая версия Java используется для компиляции (1.5, 1.6, 1.7, 1.8 и т.д.), Так что это не решаемо с помощью Maven. Но вы можете убедиться, что не используете зависимости, которые используют другую версию Java, чем вам хотелось бы иметь.
Это можно обеспечить с помощью плагина Maven Enforcer с помощью дополнительных правил enforcer:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version> <!-- find the latest version at http://maven.apache.org/plugins/maven-enforcer-plugin/ -->
<executions>
<execution>
<id>enforce-bytecode-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<enforceBytecodeVersion>
<maxJdkVersion>1.6</maxJdkVersion>
<excludes>
<exclude>org.mindrot:jbcrypt</exclude>
</excludes>
</enforceBytecodeVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.0-beta-5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
[...]
</project>
Это нарушит вашу сборку, если у вас есть зависимость, которая скомпилирована с другой версией JDK, чем вы хотите иметь.
Комментарии:
1. Это здорово. Я предполагаю, что эти правила применяются и к транзитивным зависимостям?
2. Выдержка из документов:
This rule checks the dependencies transitively and fails if any class of any dependency is having its bytecode version higher than the one specified.
Смотрите mojo.codehaus.org/extra-enforcer-rules /…3. Мне потребовалось немного поискать в Google, чтобы добраться сюда. Очень ценится.
4. может быть вызван с
mvn validate
5. Есть ли какая — то особая причина для исключения jbcrypt ?
Ответ №2:
Чтобы ответить на ваши два вопроса:
Да, это возможно. Просмотр свойств docs
, <maven.compiler.target>
и <maven.compiler.source>
просто указывает Maven, какую версию javac
использовать для компиляции вашего проекта. И я цитирую для вашей справки:
Примечание: Простая установка параметра target не гарантирует, что ваш код действительно выполняется на JRE с указанной версией. Ошибка заключается в непреднамеренном использовании API, которые существуют только в более поздних JRES, что приведет к сбою вашего кода во время выполнения с ошибкой привязки. Чтобы избежать этой проблемы, вы можете либо настроить путь к загрузочному классу компилятора в соответствии с целевой JRE, либо использовать плагин Animal Sniffer Maven, чтобы убедиться, что ваш код не использует непреднамеренные API.
Магическое число после Unsupported major.minor version
ошибки фактически указывает версию JRE, с которой совместим файл класса:
J2SE 8 = 52,
J2SE 7 = 51,
J2SE 6.0 = 50,
J2SE 5.0 = 49,
JDK 1.4 = 48,
JDK 1.3 = 47,
JDK 1.2 = 46,
JDK 1.1 = 45
Я не знаю, есть ли простой способ указать основную / второстепенную версию ВСЕХ зависимостей (и переходных зависимостей) в проекте.
ОБНОВЛЕНИЕ: хотя я не использовал его раньше, мне интересно, что плагин Animal Sniffer Maven поможет выявить основную / второстепенную версию ваших зависимостей.
Комментарии:
1. К сожалению, animal sniffer предназначен только для вашего собственного написанного кода, а не для зависимостей. Основываясь на том, что зависимость в Maven является двоичным артефактом, который был скомпилирован с любой версией, вы не можете установить версию компилятора в своей сборке для принудительного использования версий зависимостей.