在 Maven 中指定 Java 版本 - 属性和编译器插件之间的差异
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38882080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specifying java version in maven - differences between properties and compiler plugin
提问by Plebejusz
I'm not very experienced with maven and while experimenting with multi-module project I started wondering how can I specify java version for all my child modules in parent maven pom. Until today I was using just:
我对 maven 不是很有经验,在尝试多模块项目时,我开始想知道如何为父 maven pom 中的所有子模块指定 java 版本。直到今天我只使用:
<properties>
<java.version>1.8</java.version>
</properties>
but when researching I found that you can also specify java version in maven compiler plugin, like that:
但是在研究时我发现您还可以在 maven 编译器插件中指定 java 版本,如下所示:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
And then wrap this into plugin management tag to enable child poms usage of this. So the first question is what are the differences beetwen setting java version in properties and in maven compiler plugin?
然后将其包装到插件管理标签中以启用子 poms 使用它。所以第一个问题是beetwen在属性和maven编译器插件中设置java版本有什么区别?
I couldn't find clear answer but in process of researching I found that you can also specify java version in this way:
我找不到明确的答案,但在研究过程中我发现您也可以通过这种方式指定 java 版本:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
which suggest that compiler plugin is there even if I dont explicit declare it. Running mvn package outputs with
这表明即使我没有明确声明编译器插件也在那里。运行 mvn 包输出
maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---
and some other plugins that I didn't declare. So are those plugins default, hidden part of maven pom? Are there any differences beetwen setting source/target in properties and in maven plugin configuration element?
和其他一些我没有声明的插件。那么这些插件是默认的,maven pom 的隐藏部分吗?在属性和 maven 插件配置元素中设置源/目标有什么区别吗?
Some other questions are - which way should be used (and when if they are not equal)? Which one is best for multi-module project and what happens if java version specified in pom is different than version pointed in JAVA_HOME?
其他一些问题是 - 应该使用哪种方式(以及当它们不相等时)?哪个最适合多模块项目,如果 pom 中指定的 java 版本与 JAVA_HOME 中指定的版本不同,会发生什么?
采纳答案by davidxxx
How to specify the JDK version?
如何指定JDK版本?
1) <java.version>
is not referenced in the Maven documentation.
It is a Spring Boot specificity.
It allows to set the source and the target java version with the same version such as this one to specify java 1.8 for both :
1)<java.version>
未在 Maven 文档中引用。
这是 Spring Boot 的特性。
它允许将源和目标 java 版本设置为相同的版本,例如为两者指定 java 1.8:
<properties>
<java.version>1.8</java.version>
</properties>
Feel free to use it if you use Spring Boot.
如果您使用 Spring Boot,请随意使用它。
2) Using maven-compiler-plugin
or maven.compiler.source
/maven.compiler.target
properties to specify the source
and the target
are equivalent.
2) 使用maven-compiler-plugin
or 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>
and
和
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
are equivalent according to the Maven documentation of the compiler pluginsince the <source>
and the <target>
elements in the compiler configuration use the properties maven.compiler.source
and maven.compiler.target
if they are defined.
根据编译器插件的Maven 文档,它们是等效的,
因为编译器配置中的<source>
和<target>
元素使用属性maven.compiler.source
,maven.compiler.target
如果它们被定义。
The
-source
argument for the Java compiler.
Default value is:1.6
.
User property is:maven.compiler.source
.The
-target
argument for the Java compiler.
Default value is:1.6
.
User property is:maven.compiler.target
.
-source
Java 编译器的参数。
默认值为:1.6
。
用户属性是:maven.compiler.source
。
-target
Java 编译器的参数。
默认值为:1.6
。
用户属性是:maven.compiler.target
。
About the default values for source
and target
, note that
since the 3.8.0
of the maven compiler, the default values have changed from 1.5
to 1.6
.
关于source
and 的默认值target
,请注意,
自3.8.0
maven 编译器以来,默认值已从 更改1.5
为1.6
。
3) The maven-compiler-plugin 3.6
and later versions provide a new way :
3) maven-compiler-plugin3.6
及以后的版本提供了一种新的方式:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>9</release>
</configuration>
</plugin>
You could also declare just :
你也可以只声明:
<properties>
<maven.compiler.release>9</maven.compiler.release>
</properties>
But at this time it will not work as the maven-compiler-plugin
default version you use doesn't rely on a recent enough version.
但此时它不会工作,因为maven-compiler-plugin
您使用的默认版本不依赖于足够新的版本。
The Maven release
argument conveys release
: a new JVM standard option that we could pass from Java 9 :
Mavenrelease
参数传达release
:我们可以从 Java 9传递 的新 JVM 标准选项:
Compiles against the public, supported and documented API for a specific VM version.
针对特定 VM 版本的公共、支持和记录的 API 进行编译。
This way provides a standard way to specify the same version for the source
, the target
and the bootstrap
JVM options.
Note that specifying the bootstrap
is a good practice for cross compilations and it will not hurt if you don't make cross compilations either.
这种方式提供了一种标准方式来为source
、target
和bootstrap
JVM 选项指定相同的版本。
请注意,指定bootstrap
是交叉编译的一个好习惯,如果您也不进行交叉编译,也不会受到伤害。
Which is the best way to specify the JDK version?
哪个是指定 JDK 版本的最佳方式?
The first way (<java.version>
) is allowed only if you use Spring Boot.
第一种方式 ( <java.version>
) 仅在您使用 Spring Boot 时才允许。
For Java 8 and below :
对于 Java 8 及以下版本:
About the two other ways : valuing the maven.compiler.source
/maven.compiler.target
properties orusing the maven-compiler-plugin
, you can use one or the other. It changes nothing in the facts since finally the two solutions rely on the same properties and the same mechanism : the maven core compiler plugin.
关于其他两种方式:评估maven.compiler.source
/maven.compiler.target
属性或使用maven-compiler-plugin
,您可以使用其中一种。它在事实中没有任何改变,因为最终这两个解决方案依赖于相同的属性和相同的机制:maven 核心编译器插件。
Well, if you don't need to specify other properties or behavior than Java versions in the compiler plugin, using this way makes more sense as this is more concise:
好吧,如果您不需要在编译器插件中指定除 Java 版本之外的其他属性或行为,那么使用这种方式更有意义,因为它更简洁:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
From Java 9 :
从 Java 9 :
The release
argument (third point) is a way to strongly consider if you want to use the same version for the source and the target.
该release
参数(第三点),如果你想使用相同版本的源和目标,以认真考虑的一种方式。
What happens if the version differs between the JDK in JAVA_HOME and which one specified in the pom.xml?
如果 JAVA_HOME 中的 JDK 和 pom.xml 中指定的版本不同,会发生什么情况?
It is not a problem if the JDK referenced by the JAVA_HOME
is compatible with the version specified in the pom but to ensure a better cross-compilation compatibility think about adding the bootstrap
JVM option with as value the path of the rt.jar
of the target
version.
如果 JDK 引用的 JDKJAVA_HOME
与 pom 中指定的版本兼容,则不是问题,但为了确保更好的交叉编译兼容性,请考虑添加bootstrap
JVM 选项rt.jar
,并将target
版本的路径作为值。
An important thing to consider is that the source
and the target
version in the Maven configuration should not be superior to the JDK version referenced by the JAVA_HOME
.
A older version of the JDK cannot compile with a more recent version since it doesn't know its specification.
需要考虑的一个重要事项是Maven 配置中的source
和target
版本不应优于JAVA_HOME
.
旧版本的 JDK 不能用更新的版本编译,因为它不知道它的规范。
To get information about the source, target and release supported versions according to the used JDK, please refer to java compilation : source, target and release supported versions.
根据使用的 JDK 获取源、目标和发布支持的版本信息,请参阅java 编译:源、目标和发布支持的版本。
How handle the case of JDK referenced by the JAVA_HOME is not compatible with the java target and/or source versions specified in the pom?
JAVA_HOME引用的JDK与pom中指定的java目标和/或源版本不兼容的情况如何处理?
For example, if your JAVA_HOME
refers to a JDK 1.7 and you specify a JDK 1.8 as source and target in the compiler configuration of your pom.xml, it will be a problem because as explained, the JDK 1.7 doesn't know how to compile with.
From its point of view, it is an unknown JDK version since it was released after it.
In this case, you should configure the Maven compiler plugin to specify the JDK in this way :
例如,如果您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>
You could have more details in examples with maven compiler plugin.
您可以在使用 maven compiler plugin 的示例中了解更多详细信息。
It is not asked but cases where that may be more complicated is when you specify source but not target. It may use a different version in target according to the source version. Rules are particular : you can read about them in the Cross-Compilation Options part.
不会询问,但可能更复杂的情况是当您指定源而不是目标时。它可能会根据源版本在目标中使用不同的版本。规则是特殊的:您可以在交叉编译选项部分阅读有关它们的信息。
Why the compiler plugin is traced in the output at the execution of the Maven package
goal even if you don't specify it in the pom.xml?
为什么编译器插件在执行 Mavenpackage
目标时会在输出中被跟踪,即使您没有在 pom.xml 中指定它?
To compile your code and more generally to perform all tasks required for a maven goal, Maven needs tools. So, it uses core Maven plugins (you recognize a core Maven plugin by its groupId
: org.apache.maven.plugins
) to do the required tasks : compiler plugin for compiling classes, test plugin for executing tests, and so for... So, even if you don't declare these plugins, they are bound to the execution of the Maven lifecycle.
At the root dir of your Maven project, you can run the command : mvn help:effective-pom
to get the final pom effectively used. You could see among other information, attached plugins by Maven (specified or not in your pom.xml), with the used version, their configuration and the executed goals for each phase of the lifecycle.
为了编译您的代码,更一般地执行 Maven 目标所需的所有任务,Maven 需要工具。因此,它使用核心 Maven 插件(您可以通过groupId
:识别核心 Maven 插件org.apache.maven.plugins
)来执行所需的任务:用于编译类的编译器插件、用于执行测试的测试插件等等……所以,即使您不这样做声明这些插件,它们绑定到 Maven 生命周期的执行。
在 Maven 项目的根目录下,您可以运行命令 :mvn help:effective-pom
以有效使用最终的 pom。您可以看到 Maven 附加的插件(在 pom.xml 中指定或未指定)以及使用的版本、它们的配置和生命周期每个阶段的执行目标等信息。
In the output of the mvn help:effective-pom
command, you could see the declaration of these core plugins in the <build><plugins>
element, for example :
在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>
...
You can have more information about it in the introduction of the Maven lifeycle in the Maven documentation.
您可以在 Maven 文档中 Maven 生命周期的介绍中获得更多信息。
Nevertheless, you can declare these plugins when you want to configure them with other values as default values (for example, you did it when you declared the maven-compiler plugin in your pom.xml to adjust the JDK version to use) or when you want to add some plugin executions not used by default in the Maven lifecycle.
然而,当您想将它们配置为其他值作为默认值时,您可以声明这些插件(例如,您在 pom.xml 中声明 maven-compiler 插件以调整要使用的 JDK 版本时这样做)或当您想要添加一些在 Maven 生命周期中默认不使用的插件执行。
回答by Stefano
Consider the alternative:
考虑替代方案:
<properties>
<javac.src.version>1.8</javac.src.version>
<javac.target.version>1.8</javac.target.version>
</properties>
It should be the same thing of maven.compiler.source/maven.compiler.target
but the above solution works for me, otherwise the second one gets the parent specification (I have a matrioska of .pom)
它应该是一样的,maven.compiler.source/maven.compiler.target
但上面的解决方案对我有用,否则第二个得到父规范(我有一个 .pom 的 matrioska)
回答by Sen
None of the above solutions worked for me straight away. So I did the followings:-
上述解决方案都没有立即对我有用。所以我做了以下事情:-
Added
<properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties>
in pom.xml
Went to the
Project Properties > Java Build Path
, then removed the JRE System Library which was pointing toJRE1.5
.Force updated the project.
添加
<properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties>
在 pom.xml 中
转到
Project Properties > Java Build Path
,然后删除指向的 JRE 系统库JRE1.5
。强制更新了项目。