【问题标题】:Which compiler version maven is using here?maven 在这里使用的是哪个编译器版本?
【发布时间】:2016-08-27 12:45:02
【问题描述】:

我正在使用下面的 maven 编译器插件来编译我的 java 代码:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <inherited>true</inherited>
    <version>2.5.1</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
    </configuration>
</plugin>

我的 java_home 指向 Java 7。

我的第一个问题,我的类是用 java 6 还是 java 7 编译的?

如果使用 java 6(因为 &lt;source&gt;1.6&lt;/source&gt; ),maven 将如何知道 路径 java 1.6 作为 java home 指向 1.7?

如果我需要用java 1.8编译源代码,是否需要将source和target设置为1.8?

但是,maven 怎么知道 jdk 1.8 在路径中?

我需要将 java_home 更改为指向 java 8 吗?

【问题讨论】:

  • 是的,你会的。没有 1.8 jdk 就不能使用源和目标 1.8。
  • @f1sh 我没有把你带到这里。我已经安装了 jdk 1.8。我的问题是,如果我什至提到&lt;source&gt;1.8&lt;/source&gt; and &lt;target&gt;1.8&lt;/target&gt;,maven 将如何知道使用 java home 安装 jdk 1.8 的路径?
  • 它不知道,你必须将 JAVA_HOME 设置为你的 JDK 8。
  • @dunni si 我需要设置 JAVA_HOME 来挖掘 JDK 8 以及源/目标到 1.8 对吗?
  • 如果您正在进行交叉编译(从 7 到 6),我真的建议您阅读这篇 SO 帖子 stackoverflow.com/q/35913775/5606016

标签: java maven compilation


【解决方案1】:

简短回答:

  1. 由于JAVA_HOME 指向Java 1.7,因此将使用Java 1.7 中的javac 程序(编译器)。但是,由于sourcetarget 都是1.6,因此mvn compile 命令将生成可在JRE 1.6 上运行的类。如果您使用javap 实用程序查看与生成的类文件相关联的主要和次要版本号,这将是显而易见的。对于 Java 1.8,这些值是 52 and 0,对于 Java 1.7,它们是 51 and 0,对于 Java 1.6,它们是 50 and 0。您可能想知道为什么要使用 Java 1.7 编译器生成带有 target = 1.6 的类。原因取决于您要在其上运行类的运行时 (JRE)。如果您的编译器和运行时始终同意版本,您可能不会使用这些,但这些升级需要在大型团队中进行协调,同时,您应该始终尽量保持接近最新软件的版本(一个主要原因:您想要修复错误)。要记住的另一件事是source release 1.n requires target release 1.n

  2. 是的,将这些值 &lt;source&gt;&lt;target&gt; 更改为 1.8(可能有一个捷径,但让我们稍后再做吧 ;))。确保 JAVA_HOME(和 PATH)指向 JDK 1.8,因为 maven-compiler-plugin 最终使用来自插件的 &lt;configuration&gt;-source-target 参数委托给 PATH 中的 javac 程序。查看mvn -X compile 的输出,你会得到类似:


[DEBUG]   (f) source = 1.8 
[DEBUG]   (f) staleMillis = 0 
[DEBUG]   (f) target = 1.8 
[DEBUG]   (f) useIncrementalCompilation = true 
[DEBUG]   (f) verbose = false 
[DEBUG] -- end configuration -- 
[DEBUG] Using compiler 'javac'.

注意来自Maven docs 的以下警告:

仅设置target 选项并不能保证您的代码实际运行在具有指定版本的 JRE 上。陷阱是意外使用仅存在于后来的 JRE 中的 API,这会使您的代码在运行时失败并出现链接错误。为避免此问题,您可以配置编译器的引导类路径以匹配目标 JRE,或使用 Animal Sniffer Maven Plugin 来验证您的代码没有使用意外 API。

【讨论】:

  • 当我运行 javap -verbose MyController | findstr "major" 时,它返回主要版本:50。所以看起来编译器 1.6 被使用,尽管 javahome 指向 java 1.7 为什么?
  • 因为sourcetarget 设置为1.6,这意味着Java 7 编译器为JVM 6 生成字节码
  • 不,它使用 Java 7 的编译,但编译器可以生成与 Java 6 兼容的字节码。
  • @emilly,没有使用 1.6 编译器,但是 1.7 的编译器与 -source 1.6 一起使用,因为您要求它这样做。如果您忽略-source,则默认值为 1.7(1.7 编译器)、1.8(1.8 编译器)等。确保target &gt;= source
  • @khmarbaise 正如你所说的 Because source, target are set to 1.6 which means the Java 7 compiler produces bytecode for JVM 6 。但是作为javap -verbose MyController | findstr "major",将主版本返回为50。它是否应该将主版本返回为51(java 7编译器的值),因为主值告诉使用了哪个编译器?同意它将为 JVM 6 生成字节码,因为我提到目标为 1.6。
【解决方案2】:

Maven 使用在 JAVA_HOME 中设置的 JDK。您可以在 mvn.bat 中设置以查找特定的 JDK 位置。

【讨论】:

  • 不要更改mvn.batmvn。你应该使用你提到的JAVA_HOME,或者你可以使用你设置JAVA_HOME.mavenrc文件(在Windows mavenrc_pre.bat`的主文件夹中)。或者你可以使用toolchain to define the JDK which is used
猜你喜欢
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多