博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,京东购书链接:https://item.jd.com/12677623.html,扫描左侧二维码进入京东手机购书页面。 |
最近几年,整个 Java 生态圈正在并将长期处于从 JDK 8 到 JDK 17 或更高版本的升级换代中,较为典型案例是:以 Spring 为代表的 Web 应用开发框架大多已经升级到了 JDK 17,而在大数据生态圈,Flink、Spark 还在使用 JDK 8,对于那些多模块的 Maven 项目,会出现不同的 Module 使用不同版本的 JDK 问题,这给构建这类项目造成了一些困难,本文简单梳理一下这一问题的解决方法,给出最佳实践。
首先,为了能编译依赖不同 JDK 版本的项目,你在本地必须安装多个对应的 JDK,然后,选择其中一个较为常用的 JDK 设置为 JAVA_HOME
,从目前的情况来看,很多主流的 IDE,例如 IntelliJ 也都升级到子 Java 17, 所以我们建议将 Java 17 或更高版本的 JDK 设置为JAVA_HOME
, 而不是 JDK 8。
对于具体的 Maven 项目来说,尽管我们可以通过临时更改 JAVA_HOME
环境变量或在命令行中指定 javac.exe
的路径(具体参考《》),但因为每次构建项目时都执行这些琐碎的工作,所以还是很不方便的,最好的做法还是“固化“到项目的 POM 文件中,这样以后都不需要再关注该问题。
多模块的 Maven 项目通常是包含一个 Parent POM 和若干 Module POM,我们以 JDK 8 和 JDK 17 为例,建议这样修改 POM 配置:
1️⃣ 先梳理一下项目中的所有 Module,有多少是基于 JDK 8 的,多少是 JDK 17 的
2️⃣ 选择 Module 多的 JDK 版本作为 ”主 JDK“,在 Parent 的 pom.xml 中显示设置 Maven Comipler Plugin 使用的 javac.exe
路径,我们假设 ”主 JDK“ 是 JDK 8,则配置如下(注意替换 javac.exe
路径):
<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><fork>true</fork><executable>C:\Lib\Java\jdk-1.8.391\bin\javac.exe</executable><compilerVersion>1.8</compilerVersion></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><!-- disable test when building. tests will run by external testng cmd!--><configuration><skip>true</skip></configuration></plugin></plugins></pluginManagement>
</build>
surefire 的配置与本文讨论话题无关,只是和我们配置 JDK 版本的思路类似,也是想全局 disable test phase, 所以一并提供出来供复用。
3️⃣ 找到 Module 较少的 JDK 版本,也就是 ”次要 JDK“,在 Parent 的 pom.xml 中显示设置 Maven Comipler Plugin 使用的 javac.exe
路径,我们假设 ”次要 JDK“ 是 JDK 17,则配置如下(注意替换 javac.exe
路径):
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><fork>true</fork><executable>C:\Lib\Java\jdk-17.0.7\bin\javac.exe</executable><compilerVersion>17</compilerVersion></configuration></plugin></plugins>
</build>
完成上述配置后,各个模块就能使用对应的 JDK 进行编译了,且以后构建项目时也不再需要关注多版本 JDK 编译的问题了,应该说是一个比较好的最佳实践了!