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?
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.
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)
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