Настройте maven-compiler-plugin, чтобы он работал как с JDK-8, так и с JDK-12 (в проекте Spring Boot)

#java #maven #spring-boot #build #maven-compiler-plugin

#java #maven #spring-boot #сборка #maven-compiler-plugin

Вопрос:

Можно ли настроить, maven-compiler-plugin чтобы он работал как с JDK 8, так и с JDK 12? Я не уверен, актуально ли это, но это проект Spring Boot.

1. Конфигурация

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <release>8</release>
    </configuration>
</plugin>
  

компилируется под JDK-12, но под JDK-8 происходит сбой:

 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project xxxx: 
Fatal error compiling: invalid flag: --release 
  

2. Конфигурация

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
</plugin>
  

который пропускает <release>8</release> параметр, компилируется под JDK-8, но под JDK-12 завершается с ошибкой:

 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project xxxx:
Fatal error compiling: CompilerException: NullPointerException
  

Во всех возможных интернет-источниках я нашел совет использовать <release>8</release> параметр, чтобы иметь возможность избежать ошибки в JDK-12, но это отключает возможность компиляции в JDK-8.

Наша совместимость с исходным кодом и целью — Java 8, и нам нужно создать код на старом добром plain mvn clean install (без предоставления профиля!) на машинах разработчиков с JDK-12, но также и на Jenkins, где мы все еще должны сохранить JDK-8, и у нас также есть несколько консервативных разработчиков 🙂

Ответ №1:

сначала вы должны определить maven-compiler-plugin в pluginManagement следующим образом:

   <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
      <...>
    ...
  

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

   <profiles>
    <profile>
      <id>jkd-12-compile</id>
      <activation>
        <jdk>12</jdk>
      </activation>
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                <release>8</release>
              </configuration>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </profile>
    <profile>
      <id>jdk-8-compile</id>
      <activation>
        <jdk>[,8]</jdk>
      </activation>
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                <source>8</source>
                <target>8</target>
              </configuration>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </profile>
  </profiles>
  

Обычно не mvn clean install не требуется. Обычно вам нужно только mvn clean verify

Комментарии:

1. Наконец, он работает с <jdk>(,9)</jdk> и <jdk>[9,)</jdk> . Потому что <jdk>[,8]</jdk> есть проблема с версиями, подобными 8.0.152 или около того… Большое спасибо!

2. Кстати, можете ли вы объяснить, зачем все это нужно? Я не имею в виду профили, они понятны, но почему я не могу использовать только одну конфигурацию для всех JDK. Я попробовал одну конфигурацию POM с простой командной строкой Java «Hello world», и это работает одинаково во всех JDK. Это из-за чего-то в Spring Boot?

3. Это будет не так просто из-за NDA. Я попытаюсь извлечь анонимизированный MCVE, когда у меня будет время.

Ответ №2:

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

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

<profiles>
  <profile>
    <id>jdk9 </id>
    <activation>
      <jdk>[9,)</jdk>
    </activation>
    <properties>
      <maven.compiler.release>8</maven.compiler.release>
    </properties>
  </profile>
</profiles>
  

Наслаждайтесь!

Комментарии:

1. Это приятно. Вы могли бы просто добавить профиль, который должен быть активным при обнаружении JDK 8, чтобы иметь полностью функциональный раздел profiles, который, я думаю, сделал бы ваш ответ еще лучше.

2. @Paulo maven.compiler.target и maven.compiler.source могут остаться в главном properties разделе, поскольку они будут проигнорированы 9

3. Отлично! Теперь, когда вы добавили свойства вместе с профилем, это решение определенно лучше. Спасибо!

4. @greut — как мне точно узнать, какую версию установить в теге properties? Я хочу использовать Java 10. Должен ли я установить версию как 10 или 1.10?

5. @MasterJoe2 Я бы сказал 10, docs.oracle.com/javase/1.5.0/docs/relnotes/version-5.0.html