Określanie wersji Javy w maven-różnice między właściwościami i wtyczką kompilatora

Nie mam zbyt dużego doświadczenia z mavenem i eksperymentując z projektem wielomodułowym zacząłem się zastanawiać, jak Mogę określić wersję Javy dla wszystkich moich modułów potomnych w Maven pom rodzica. Do dzisiaj używałem tylko:

<properties>
    <java.version>1.8</java.version>
</properties>

Ale podczas badania odkryłem, że można również określić wersję Javy w wtyczce kompilatora maven, Tak:

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

A następnie zawiń to w znacznik zarządzania wtyczkami, aby umożliwić korzystanie z pomów potomnych. Więc pierwsze pytanie brzmi jakie są różnice w ustawieniu wersji Javy we właściwościach i w wtyczce kompilatora maven?

Nie mogłem znaleźć jasnej odpowiedzi, ale w trakcie badania odkryłem, że można również określić wersję Javy w ten sposób:

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

Które sugerują, że wtyczka kompilatora jest tam, nawet jeśli nie deklaruję tego wyraźnie. Uruchamianie pakietów mvn z

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

I kilka innych wtyczek, których nie zadeklarowałem. więc te wtyczki są domyślne, ukryta część maven pom? Czy są jakieś różnice w ustawieniu źródła/celu we właściwościach i w elemencie konfiguracji wtyczki Maven?

Inne pytania to-w jaki sposób należy użyć (i kiedy, jeśli nie są równe)? Która z nich jest najlepsza dla projektu wielomodułowego i co się stanie, jeśli wersja java określona w pom jest inna niż wersja wskazana w JAVA_HOME?

Author: Gray, 2016-08-10

2 answers

Jak określić wersję JDK?

1) <java.version> nie jest wymieniony w dokumentacji Maven.
Jest to specyfika sprężynowego buta.
Pozwala to ustawić źródłową i docelową wersję Javy z tą samą wersją, taką jak ta, aby określić java 1.8 Dla obu:

<properties>
     <java.version>1.8</java.version>
</properties>   

Możesz go używać, jeśli używasz sprężynowego buta.

2) za pomocą maven-compiler-plugin lub maven.compiler.source/maven.compiler.target Właściwości określające source i target są równoważne.

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

I

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

Są równoważne zgodnie z dokumentacja Mavena wtyczki kompilatora ponieważ elementy <source> i <target> w konfiguracji kompilatora używają właściwości maven.compiler.source i maven.compiler.target, jeśli są zdefiniowane.

Źródło

Argument -source kompilatora Javy.
Wartość domyślna to: 1.6.
Właściwością użytkownika jest: maven.compiler.source.

Cel

Argument -target dla kompilator Javy.
Wartość domyślna to: 1.6.
Właściwością użytkownika jest: maven.compiler.target.

O wartościach domyślnych dla source i target, zauważ, że od 3.8.0 kompilatora maven, wartości domyślne zmieniły się z 1.5 na 1.6.

3) maven-compiler-plugin 3.6 i nowsze wersje zapewniają nowy sposób:

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

Można też zadeklarować tylko:

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

Ale w tej chwili nie będzie działać jako maven-compiler-plugin domyślne wersja, której używasz, nie zależy od najnowszej wersji.

Argument Maven release przekazuje release: nową standardową opcję JVM , którą możemy przekazać z Javy 9:

Kompiluje z publicznym, wspieranym i udokumentowanym API dla konkretna wersja maszyny wirtualnej.

Ten sposób zapewnia standardowy sposób określenia tej samej wersji dla opcji source, target I bootstrap JVM.
Należy zauważyć, że określenie bootstrap jest dobrą praktyką dla Kompilacje krzyżowe i nie zaszkodzi, jeśli nie zrobisz kompilacji krzyżowych.


Jaki jest najlepszy sposób na określenie wersji JDK?

Pierwszy sposób (<java.version>) jest dozwolony tylko wtedy, gdy używasz Spring Boot.

Dla Java 8 i poniżej:

O dwóch innych sposobach: wartościowanie maven.compiler.source/maven.compiler.target właściwości lub używając maven-compiler-plugin, możesz użyć jednej lub drugiej. To nic nie zmienia w faktach, ponieważ w końcu dwa rozwiązania opierają się na tych samych właściwościach i tym samym mechanizmie: wtyczce kompilatora Maven core.

Cóż, jeśli nie musisz określać innych właściwości lub zachowań niż wersje Javy we wtyczce kompilatora, użycie tego sposobu ma większy sens, ponieważ jest to bardziej zwięzłe:

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

Z Javy 9 :

Argument release (trzeci punkt) jest sposobem na zdecydowane rozważenie, czy chcesz użyć tej samej wersji dla źródła i celu.

Co? dzieje się, jeśli wersja różni się między JDK w JAVA_HOME i która z nich jest określona w pom.xml?

Nie jest problemem, jeśli JDK, do którego odwołuje się JAVA_HOME, jest kompatybilny z wersją podaną w pom, ale aby zapewnić lepszą kompatybilność cross-compilation, pomyśl o dodaniu opcji bootstrap JVM z wartością jako ścieżką rt.jar wersji target.

Ważną rzeczą do rozważenia jest to, że wersja source i target W Maven konfiguracja nie powinna być lepsza od wersji JDK, do której odwołuje się JAVA_HOME.
Starsza wersja JDK nie może skompilować się z nowszą wersją, ponieważ nie zna swojej specyfikacji.

Aby uzyskać informacje o wersjach źródłowych, docelowych i release obsługiwanych zgodnie z używanym JDK, zapoznaj się z java compilation : source, target I release obsługiwane wersje.


Jak obsłużyć przypadek JDK, do którego odwołuje się JAVA_HOME to nie jest kompatybilny z docelowymi i/lub źródłowymi wersjami Javy podanymi w pom?

Na przykład, jeśli JAVA_HOME odnosi się do JDK 1.7 i podajesz JDK 1.8 jako źródło i cel w konfiguracji kompilatora twojego pom.xml, będzie problem bo jak wyjaśniłem JDK 1.7 nie wie jak się skompilować.
Z jego punktu widzenia jest to nieznana wersja JDK, ponieważ została wydana po nim.
W takim przypadku należy skonfigurować wtyczkę kompilatora Maven do podaj JDK w ten sposób:

<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>

Możesz mieć więcej szczegółów w przykładach z wtyczką kompilatora maven .


Nie jest pytany, ale przypadki, w których może to być bardziej skomplikowane, to gdy podasz źródło, ale nie cel. Może używać innej wersji w target w zależności od wersji źródłowej. Zasady są szczególne : możesz przeczytać o nich w w części opcje kompilacji krzyżowej .


Dlaczego wtyczka kompilatora jest śledzona w wyjście podczas wykonywania celu Maven package, nawet jeśli nie podasz go w pom.xml?

Aby skompilować kod i ogólnie wykonać wszystkie zadania wymagane dla celu Mavena, Maven potrzebuje narzędzi. Tak więc używa rdzeniowych wtyczek Mavena (rozpoznajesz rdzeń wtyczki Mavena po jego groupId : org.apache.maven.plugins) aby wykonać wymagane zadania: wtyczka kompilatora do kompilowania klas, wtyczka testowa do wykonywania testów i tak dalej... Tak więc, nawet jeśli nie zadeklarujesz tych wtyczek, są one związane z wykonanie cyklu życia Maven.
W katalogu głównym Twojego projektu Maven możesz uruchomić polecenie: mvn help:effective-pom, aby efektywnie wykorzystać końcowy pom. Możesz zobaczyć między innymi załączone wtyczki przez Mavena (określone lub nie w Twoim pom.xml), z używaną wersją, ich konfiguracją i wykonanymi celami dla każdej fazy cyklu życia.

Na wyjściu polecenia mvn help:effective-pom można było zobaczyć deklarację tych podstawowych wtyczek w elemencie <build><plugins>, na przykład :

...
<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>
  ...
Więcej informacji na ten temat można znaleźć w wprowadzeniu cyklu życia Mavena w dokumentacji Mavena.

Niemniej jednak, możesz zadeklarować te wtyczki, gdy chcesz je skonfigurować z innymi wartościami jako wartości domyślne (na przykład, zrobiłeś to, gdy zadeklarowałeś wtyczkę Maven-compiler w swoim pom.xml, aby dostosować wersję JDK do użycia) lub gdy chcesz dodać niektóre wykonania wtyczek nie używane domyślnie w cyklu życia Mavena.

 153
Author: davidxxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-27 10:19:20

Rozważmy alternatywę:

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

Powinno być to samo z maven.compiler.source/maven.compiler.target ale powyższe rozwiązanie działa dla mnie, w przeciwnym razie drugie dostaje specyfikację rodzica (mam matrioskę z .pom)

 0
Author: Stefano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 09:51:13