it-swarm.com.ru

Указание версии Java в maven - различия между свойствами и плагином компилятора

Я не очень разбираюсь в maven и, экспериментируя с многомодульным проектом, я начал задумываться, как я могу указать Java версию для всех моих дочерних модулей в родительском maven pom. До сегодняшнего дня я использовал только:

<properties>
    <Java.version>1.8</Java.version>
</properties>

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

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

А затем оберните это в тег управления плагином, чтобы разрешить использование этого дочерними помпами. Итак, первый вопрос - каковы различия между настройкой Java версии в свойствах и в плагине компилятора maven?

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

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

которые предполагают, что плагин компилятора есть, даже если я не объявил об этом явно. Запуск выводов пакета mvn с

maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---

и некоторые другие плагины, которые я не объявил. Значит, эти плагины по умолчанию, скрытая часть maven pom? Есть ли различия между настройкой источника/цели в свойствах и в элементе конфигурации плагина maven?

Некоторые другие вопросы - какой путь следует использовать (и когда, если они не равны)? Какой вариант лучше всего подходит для многомодульного проекта, и что произойдет, если версия Java, указанная в pom, отличается от версии, указанной в Java_HOME?

131
Plebejusz

Как указать версию JDK?

1) <Java.version> не упоминается в документации Maven.
Это специфика Spring Boot.
Позволяет установить исходную и целевую версии Java с одинаковой версией, такой как эта, чтобы указать Java 1.8 для обоих:

<properties>
     <Java.version>1.8</Java.version>
</properties>   

Не стесняйтесь использовать его, если вы используете Spring Boot.

2) Использование свойств maven-compiler-plugin или maven.compiler.source/maven.compiler.target для указания source и target эквивалентны.

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

а также

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

эквивалентны в соответствии с документация Maven плагина компилятора , поскольку элементы <source> и <target> в конфигурации компилятора используют свойства maven.compiler.source и maven.compiler.target, если они определены.

источник

Аргумент -source для компилятора Java.
Значение по умолчанию: 1.6.
Свойство пользователя: maven.compiler.source.

цель

Аргумент -target для компилятора Java.
Значение по умолчанию: 1.6.
Свойство пользователя: maven.compiler.target.

Что касается значений по умолчанию для source и target, обратите внимание, что начиная с 3.8.0 компилятора maven значения по умолчанию изменились с 1.5 на 1.6 .

3) Плагин maven-compiler-plugin 3.6 и более поздние версии предоставляют новый способ:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>9</release>
    </configuration>
</plugin>

Вы также можете объявить просто:

<properties>
    <maven.compiler.release>9</maven.compiler.release>
</properties>

Но в настоящее время он не будет работать, поскольку используемая по умолчанию версия maven-compiler-plugin не использует достаточно недавнюю версию.

Аргумент Maven release передает release: a новый стандартный параметр JVM , который мы можем передать из Java 9:

Компилируется с общедоступным, поддерживаемым и документированным API для конкретной версии VM.

Этот способ предоставляет стандартный способ указания одной и той же версии для параметров JVM source, target и bootstrap.
Обратите внимание, что указание bootstrap является хорошей практикой для кросс-компиляции и не повредит, если вы не сделаете кросс-компиляцию.


Как лучше всего указать версию JDK?

Первый способ (<Java.version>) разрешен, только если вы используете Spring Boot.

Для Java 8 и ниже:

О двух других способах: оценивая свойства maven.compiler.source/maven.compiler.target или с помощью maven-compiler-plugin, вы можете использовать один или другой. Это ничего не меняет в фактах, поскольку в конечном итоге оба решения опираются на одни и те же свойства и один и тот же механизм: плагин компилятора ядра maven.

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

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

От Java 9:

Аргумент release (третий пункт) - это способ решительно рассмотреть, хотите ли вы использовать одну и ту же версию для источника и цели.

Что произойдет, если версия отличается между JDK в Java_HOME и той, которая указана в pom.xml?

Это не проблема, если JDK, на который ссылается Java_HOME, совместим с версией, указанной в pom, но для обеспечения лучшей совместимости с кросс-компиляцией подумайте о добавлении опции JVM bootstrap со значением в качестве пути rt.jar версии target.

Важно учитывать, что версии source и target в конфигурации Maven не должны превосходить версию JDK, на которую ссылается Java_HOME.
Более старая версия JDK не может быть скомпилирована с более новой версией, так как не знает ее спецификации.

Чтобы получить информацию об исходной, целевой и выпускной поддерживаемых версиях в соответствии с используемым JDK, обратитесь к Компиляция Java: исходная, целевая и выпускная поддерживаемые версии .


Как обрабатывать случай JDK, на который ссылается Java_HOME, несовместим с целевой и/или исходной версией Java, указанной в pom?

Например, если ваш Java_HOME ссылается на JDK 1.7 и вы указываете JDK 1.8 в качестве источника и цели в конфигурации компилятора вашего pom.xml, это будет проблемой, потому что, как объяснено, JDK 1.7 не знает, как скомпилировать с.
С его точки зрения, это неизвестная версия JDK, так как она была выпущена после нее.
В этом случае вы должны сконфигурировать плагин компилятора Maven, чтобы указать JDK следующим образом:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerVersion>1.8</compilerVersion>      
        <fork>true</fork>
        <executable>D:\jdk1.8\bin\javac</executable>                
    </configuration>
</plugin>

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


Это не спрашивается, но случаи, когда это может быть более сложным, это когда вы указываете источник, но не цель. Он может использовать другую версию в соответствии с исходной версией. Особые правила: о них можно прочитать в часть "Параметры кросс-компиляции" .


Почему плагин компилятора отслеживается в выводе при выполнении цели Maven package, даже если вы не указали его в pom.xml?

Для компиляции вашего кода и в целом для выполнения всех задач, необходимых для достижения цели maven, Maven нужны инструменты. Таким образом, он использует основные плагины Maven (основной плагин Maven по его groupId: org.Apache.maven.plugins) для выполнения необходимых задач: плагин компилятора для компиляции классов, плагин test для выполнения тестов и т.д. Итак, даже если вы не Не объявляйте эти плагины, они связаны с выполнением жизненного цикла Maven.
В корневом каталоге вашего проекта Maven вы можете запустить команду: mvn help:effective-pom, чтобы эффективно использовать последний pom. Вы можете увидеть среди прочего информацию о подключенных плагинах Maven (указанных или не указанных в вашем pom.xml), с использованной версией, их конфигурацией и выполненными целями для каждой фазы жизненного цикла.

В выводе команды mvn help:effective-pom вы могли видеть объявление этих основных плагинов в элементе <build><plugins>, например:

...
<plugin>
   <artifactId>maven-clean-plugin</artifactId>
   <version>2.5</version>
   <executions>
     <execution>
       <id>default-clean</id>
       <phase>clean</phase>
       <goals>
         <goal>clean</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <executions>
     <execution>
       <id>default-testResources</id>
       <phase>process-test-resources</phase>
       <goals>
         <goal>testResources</goal>
       </goals>
     </execution>
     <execution>
       <id>default-resources</id>
       <phase>process-resources</phase>
       <goals>
         <goal>resources</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>3.1</version>
   <executions>
     <execution>
       <id>default-compile</id>
       <phase>compile</phase>
       <goals>
         <goal>compile</goal>
       </goals>
     </execution>
     <execution>
       <id>default-testCompile</id>
       <phase>test-compile</phase>
       <goals>
         <goal>testCompile</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
  ...

Вы можете получить больше информации об этом в введение жизненного цикла Maven в документацию Maven .

Тем не менее вы можете объявить эти плагины, когда хотите настроить их с другими значениями в качестве значений по умолчанию (например, вы сделали это, когда объявили плагин maven-compiler в своем файле pom.xml для настройки используемой версии JDK) или когда вы хочу добавить некоторые исполнения плагинов, не используемые по умолчанию в жизненном цикле Maven.

225
davidxxx

Ни одно из вышеперечисленных решений не сработало для меня сразу. Итак, я сделал следующее:

  1. Добавленной

    <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties>

    в pom.xml

  2. Перешел к Project Properties > Java Build Path, затем удалил системную библиотеку JRE, которая указывала на JRE1.5.

  3. Принудительно обновил проект.

1
Sen

Рассмотрим альтернативу:

<properties>
    <javac.src.version>1.8</javac.src.version>
    <javac.target.version>1.8</javac.target.version>
</properties>

Это должно быть то же самое, что и maven.compiler.source/maven.compiler.target, но вышеупомянутое решение работает для меня, в противном случае второе получает родительскую спецификацию (у меня матриоска из .pom)

0
Stefano