我对maven不太熟悉,在尝试多模块项目时,我开始想知道如何为父maven pom中的所有子模块指定java版本。直到今天我才使用:
<properties>
<java.version>1.8</java.version>
</properties>
但在研究时我发现你也可以在maven编译器插件中指定java版本,如:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
然后将其包装到插件管理标记中以启用子poms的使用。所以第一个问题是在属性和maven编译器插件中设置java版本有什么区别?
我无法找到明确的答案,但在研究过程中我发现你也可以用这种方式指定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插件配置元素中设置源/目标是否有任何差异?
其他一些问题是 - 应该采用哪种方式(以及何时不相等)?哪一个最适合多模块项目,如果在pom中指定的java版本与JAVA_HOME中指向的版本不同,会发生什么?
答案 0 :(得分:219)
如何指定JDK版本?
1)Maven文档中未引用<java.version>
这是一个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>
根据{{3}},是等效的
由于编译器配置中的<source>
和<target>
元素使用属性maven.compiler.source
和maven.compiler.target
(如果已定义)。
Maven documentation of the compiler plugin
Java编译器的
-source
参数 默认值为:1.6
。
用户属性为:maven.compiler.source
。Java编译器的
-target
参数 默认值为:1.6
。
用户属性为:maven.compiler.target
。
关于source
和target
的默认值,请注意
target。
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
:我们可以从Java 9传递的since the 3.8.0
of the maven compiler, the default values have changed from 1.5
to 1.6
:
针对a的公共,支持和记录的API进行编译 特定的VM版本。
这种方式提供了一种标准方法,可以为source
,target
和bootstrap
JVM选项指定相同的版本。
请注意,指定bootstrap
是交叉编译的好习惯,如果您不进行交叉编译也不会受到影响。
指定JDK版本的最佳方式是哪种?
只有在使用Spring Boot时才允许第一种方式(<java.version>
)。
对于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
参数(第三点)是一种强烈考虑是否要对源和目标使用相同版本的方法。
如果JAVA_HOME中的JDK与pom.xml中指定的JDK版本不同,会发生什么?
如果JAVA_HOME
引用的JDK与pom中指定的版本兼容但是为了确保更好的交叉编译兼容性,请考虑添加bootstrap
JVM选项,这不是问题。重视rt.jar
版本的target
的路径。
需要考虑的一件重要事情是,Maven配置中的source
和target
版本不应优于JAVA_HOME
引用的JDK版本。
旧版本的JDK无法使用更新版本进行编译,因为它不了解其规范。
要根据使用的JDK获取有关源,目标和发行版支持版本的信息,请参阅new JVM standard option 。
如何处理JAVA_HOME引用的JDK的情况与pom中指定的java目标和/或源版本不兼容?
例如,如果您的JAVA_HOME
引用了JDK 1.7,并且在pom.xml的编译器配置中指定了JDK 1.8作为源和目标,那么这将是一个问题,因为正如所解释的那样,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>
您可以在java compilation : source, target and release supported versions中获得更多详细信息。
没有被问到,但是当你指定来源而不是目标时,可能更复杂的情况。根据源版本,它可能在目标中使用不同的版本。规则很特别:您可以在examples with maven compiler plugin中了解它们。
为什么即使您没有在pom.xml中指定编译器插件,也会在执行Maven package
目标时在输出中跟踪编译器插件?
要编译代码,更一般地说,为了执行maven目标所需的所有任务,Maven需要工具。因此,它使用核心Maven插件(您可以通过其groupId
识别核心Maven插件:org.apache.maven.plugins
)来执行所需的任务:编译器插件用于编译类,测试插件用于执行测试,等等。 ..因此,即使您没有声明这些插件,它们也必然会执行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>
...
您可以在the Cross-Compilation Options part中获得有关它的更多信息。
然而,当你想用其他值配置它们作为默认值时,可以声明这些插件(例如,你在pom.xml中声明maven-compiler插件以调整要使用的JDK版本时就这样做了)或者当您想要添加默认情况下在Maven生命周期中未使用的某些插件执行时。
答案 1 :(得分:1)
以上解决方案均无法立即为我工作。所以我做了以下事情:-
已添加
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
在pom.xml中
转到项目Properties> Java Build Path,然后删除JRE 指向JRE1.5的系统库。
强制更新了项目。
答案 2 :(得分:1)
以下步骤对我来说就像魅力一样!所以想与大家分享。
这些是我在 pom.xml 文件中添加的用于处理基本项目的行。我使用的是 Java 12(您可以替换您的 11、10、1.8 等)。
<properties>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
</plugins>
</build>
更改 pom 文件后,请重新加载您的项目,以便 IDE 可以将插件下载/提取到项目中。 (对于 IntelijIDEA:右键单击 pom.xml -> 转到 maven -> 重新加载项目)。
请确保也在您的 IDE 中配置所需的版本。
答案 3 :(得分:0)
考虑替代方案:
<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的matrioska)
答案 4 :(得分:0)
对于 NetBeans IDE,更改项目属性 - (Jersey Service) - Categories > Sources > 选择“源/二进制格式”为 1.8。
答案 5 :(得分:-2)
解决此问题的其他方法是重写java变量:
在命令中
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_271
export JAVA_HOME=<java-8-home-folder>
要验证版本,请在命令中输入:
mvn –version
如果一切都很好,则外观如下:
Apache Maven 3.6.2 (40f52333136460xxxxxxxxxxxxxxxxxxxx; 2019-08-27T10:06:16-05:00)
Maven home: C:\AEM\apache-maven-3.6.2\bin\..
Java version: 1.8.0_271, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_271\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"