边实验边分析-Maven默认选择JDK规则以及如何使用指定JDK版本进行编译

边实验边分析-Maven默认选择JDK规则以及如何使用指定JDK版本进行编译

Maven默认使用的是JAVA_HOME的环境变量来找到Java环境进行编译的,官网上有明确说明

在这里插入图片描述

其说明了maven会找JAVA_HOME和Path里面的Java配置,这边可能有人会问了,那如果我配了多个Java环境的情况会如何?最好的办法我们自己实践一下,这边我把我的实践结果告诉大家:

  • 配置了JAVA_HOME, 则会优先选择该环境配置,并且如果你的JAVA_HOME环境是一个错误的环境,则执行maven插件的时候会直接报错。
  • 未配置JAVA_HOME, 则会找Path里面的环境配置,并且如果你的Path里面还配置了多个Java可执行环境,则会按照先后顺序进行选择。
  • 如果都未配置,则直接报错。

上面说到的都是maven的默认行为,那么我们是否可以自己指定maven用哪个java版本进行编译呢?这边官网也给出了2种方式https://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html,具体是:

​ 一种是使用工具链指定,这边给出官网地址:https://maven.apache.org/guides/mini/guide-using-toolchains.html,这种方式比较复杂一点,但是是官方推荐的,其优点是可以全局对编译插件进行设置,这边不展开讲这种方式,官网已经比较详细说明了用法。

​ 另一种是我们可以强制对某一插件进行指定,在这里我们直接对compile插件进行强制的配置,来指定我们想要使用的JDK版本,如下

<plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><fork>true</fork><executable>${JAVA_HOME_HIGH}\bin\javac</executable><encoding>UTF-8</encoding></configuration></plugin>

我们直接配置executable为一个高版本的JDK中的javac,我们使用了一个环境变量JAVA_HOME_HIGH来避免将路径写死,并且我们配置fork为true,这样才能使得executable属性生效。

关于compilerVersion属性,实验发现,该属性只作用于该插件,并不会影响到我们编译项目使用的JDK版本。

以上则是Maven如何使用不同的JDK版本对我们的项目进行编译的方式,另外,我们即使使用同一个JDK版本进行编译,我们也能够指定不同的JDK版本,这需要归功于Javac的-source-target

这两个参数,通过这两个参数,我们可以指定编译的目标版本和编译的兼容版本,在maven的pom文件里,我们可以加入这两个配置

<project>

​	[...]

​	<properties>

  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  	<maven.compiler.target>8</maven.compiler.target>

  	<maven.compiler.source>8</maven.compiler.source>

 	</properties>

​	[...]

</project>

这边我们指定了source和target为8,即Java1.8,这样,即使我们像上面一样指定了使用JAVA 11的JDK进行编译,maven在编译的时候也会为我们加上-source和-target参数,我们可以使用mvn compile -X -f “path.pom” 命令来查看具体的编译debug日志输出,可以找到如下图:

在这里插入图片描述

这样我们就完成了,另外这边需要注意,你在设置-source和-target参数的时候一定要保证maven在使用的JDK版本支持,不然也会编译失败哦。

另外记录一个在项目中发生的问题,也是这个问题导致了上面的这些研究,最近有个项目使用maven作为编译工具,使用VSCode进行开发,使用了okhttp版本为3.14.9,由于本身是个库,所以将okhttp源码导入进了库中,以免与使用方冲突,在编译项目的时候,使用了1.8.0_144的JDK进行编译,发现会报错,在Android10Platform的类中,JAVAX库的SSLSocket类中getApplicationProtocol方法会找不到(还有一个setApplicationProtocols一样找不到),查了API文档,发现这个方法的记载有些好玩,在JAVA1.8的API文档上写的1.8支持,但是在1.9的文档上又写了1.9才支持这个方法,但是问题确实是有,所以使用了java11版本,指定1.8进行编译,编译通过了。但后来在打包机上发现,openJDK 1.8.0.282版本里面是有这个方法的,只是该方法没实现而已,附上我自己找的JDK中的rt.jar里面看到的1.8.0_144和openJDK 1.8.0.282里面这个方法的差别:

在这里插入图片描述

上图是从1.8.0_144的rt.jar

在这里插入图片描述

这个是openJDK 1.8.0.282里面拿到的。着实有点坑。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡卡爾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值