如何指定JDK版本?
使用以下三种方式中的任何一种:(1) Spring Boot 功能,或将 Maven 编译器插件与 (2) source & target 或 (3) 与 release 一起使用。
春季启动
-
<java.version> 未在 Maven 文档中引用。
这是 Spring Boot 的特殊性。
它允许将源和目标 java 版本设置为相同的版本,例如为两者指定 java 1.8:
1.8
如果您使用 Spring Boot,请随意使用它。
maven-compiler-plugin 与 source & target
- 使用
maven-compiler-plugin 或maven.compiler.source/maven.compiler.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 documentation of the compiler plugin
因为编译器配置中的<source> 和<target> 元素使用属性maven.compiler.source 和maven.compiler.target(如果已定义)。
source
Java 编译器的 -source 参数。
默认值为:1.6。
用户属性为:maven.compiler.source。
target
Java 编译器的 -target 参数。
默认值为:1.6.
用户属性为:maven.compiler.target。
关于source 和target 的默认值,请注意
since the 3.8.0 of the maven compiler, the default values have changed from 1.5 to 1.6.
maven-compiler-plugin 与 release 而不是 source & target
-
maven-compiler-plugin3.6及以后的版本提供了一种新的方式:
org.apache.maven.plugins
maven 编译器插件
3.8.0
9
你也可以只声明:
<properties>
<maven.compiler.release>9</maven.compiler.release>
</properties>
但此时它不会起作用,因为您使用的maven-compiler-plugin 默认版本不依赖于足够新的版本。
Maven release 参数传达 release :我们可以从 Java 9 传递的 new JVM standard option :
针对公共、受支持和记录的 API 编译
特定的 VM 版本。
这种方式提供了一种为source、target 和bootstrap JVM 选项指定相同版本的标准方式。
请注意,指定bootstrap 是交叉编译的好习惯,如果您不进行交叉编译也不会受到影响。
指定 JDK 版本的最佳方式是什么?
第一种方式(<java.version>)只有在使用 Spring Boot 时才允许使用。
对于 Java 8 及以下版本:
关于其他两种方法:使用maven-compiler-plugin 评估maven.compiler.source/maven.compiler.target 属性或,您可以使用其中一种。它没有改变任何事实,因为最终这两种解决方案依赖于相同的属性和相同的机制: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 中指定的版本不同会怎样?
JAVA_HOME 引用的 JDK 是否与 pom 中指定的版本兼容不是问题,但为了确保更好的交叉编译兼容性,请考虑添加 bootstrap JVM 选项,并将路径作为值target 版本的rt.jar。
需要考虑的重要一点是,Maven 配置中的source 和target 版本不应优于JAVA_HOME 引用的JDK 版本。
较旧版本的 JDK 无法与较新版本一起编译,因为它不知道其规范。
根据使用的JDK获取源、目标和发布支持的版本信息,请参考java compilation : source, target and release supported versions。
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>
您可以在examples with maven compiler plugin了解更多详情。
没有询问,但可能更复杂的情况是您指定源而不是目标。它可能会根据源版本在目标中使用不同的版本。规则是特殊的:你可以在the Cross-Compilation Options part阅读它们。
为什么在执行 Maven package 目标时在输出中跟踪编译器插件,即使您没有在 pom.xml 中指定它?
要编译您的代码,并且更普遍地执行 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 introduction of the Maven lifeycle in the Maven documentation了解更多信息。
尽管如此,当您想将这些插件配置为其他值作为默认值时,您可以声明这些插件(例如,您在 pom.xml 中声明 maven-compiler 插件以调整要使用的 JDK 版本时就这样做了)或者当你想添加一些在 Maven 生命周期中默认不使用的插件执行时。