使用 Maven 设置 Java 编译器的 -source 和 -target - 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5113030/
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
Setting the -source and -target of the Java Compiler with Maven - doesn't work
提问by His
I have set my pom file to ask Maven to compile my source code to be version 1.5 compatible using the source
and target
config params. Here is my pom:
我已将我的 pom 文件设置为要求 Maven 使用source
和target
配置参数将我的源代码编译为与 1.5 版兼容。这是我的pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
And I have a simple main class like this:
我有一个简单的主类,如下所示:
package com.user;
public class Test
{
public static void main(String[] argv)
{
System.out.println("".isEmpty());
}
}
String#isEmpty()
was introduced since Java 1.6. However, compiling my code with mvn compile
works, while I would have expected it to fail because I have set Maven to compile my code to Java 1.5 and String#isEmpty
was introduced in Java 1.6. Could anyone please suggest what I might have done wrong? What is the correct way to force Maven to use a particular Java version when compiling?
String#isEmpty()
从 Java 1.6 开始引入。但是,编译我的代码mvn compile
有效,虽然我预计它会失败,因为我已将 Maven 设置为将我的代码编译为 Java 1.5 并String#isEmpty
在 Java 1.6 中引入。任何人都可以请建议我可能做错了什么?编译时强制 Maven 使用特定 Java 版本的正确方法是什么?
For information, I am using Apache Maven 2.2.1 and javac 1.6.0_19.
有关信息,我使用的是 Apache Maven 2.2.1 和 javac 1.6.0_19。
Thanks.
谢谢。
回答by Mike Reedell
From the note at the bottom of the compiler-plugin page:
从编译器插件页面底部的注释:
Merely setting the target option does not guarantee that your code actually runs on a JRE with the specified version. The pitfall is unintended usage of APIs that only exist in later JREs which would make your code fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath to match the target JRE or use the Animal Sniffer Maven Plugin to verify your code doesn't use unintended APIs
仅设置 target 选项并不能保证您的代码实际上在具有指定版本的 JRE 上运行。陷阱是无意中使用了仅存在于后续 JRE 中的 API,这会使您的代码在运行时因链接错误而失败。为避免此问题,您可以配置编译器的启动类路径以匹配目标 JRE 或使用 Animal Sniffer Maven 插件来验证您的代码没有使用意外的 API
This means that although you're generating 1.5-level bytecode, you can still (unintentionally) call a 1.6 API method. To flag these invalide API calls, use the plugin they mention.
这意味着尽管您正在生成 1.5 级字节码,但您仍然可以(无意中)调用 1.6 API 方法。要标记这些无效的 API 调用,请使用他们提到的插件。
回答by ColinD
You need to compile with a lower version of Java if you want it to not find String.isEmpty()
. The source level controls language-level features you can and can't use, such as @Override
on interfaces requiring compilation with source level 1.6. The target level controls the compatibility of the bytecode that compilation produces. Neither have anything to do with available APIs... that's all based on the classpath you use when building, which in your case includes Java 1.6.
如果您希望它找不到String.isEmpty()
. 源代码级别控制您可以使用和不能使用的语言级别功能,例如@Override
在需要使用源代码级别 1.6 进行编译的接口上。目标级别控制编译产生的字节码的兼容性。两者都与可用的 API 无关……这完全基于您在构建时使用的类路径,在您的情况下包括 Java 1.6。