引言
简单记录RocketMq的JDK8以上版本的编译问题,在RocketMq的github - issue里面讨论还挺多的。
总得来说是个小问题,但是居然没啥文章介绍过,难道都是JDK8去部署RocketMq的源码的么?
报错问题
因为IDEA缓存的存在,很有可能看到这些内容不是爆红而是正常导入的,此时编译却会诡异般的报错。
- java: 程序包sun.nio.ch不存在
- sun.util.locale.BaseLocale.SEP不存在
Idea的报错情况
在Idea 2021.1 的版本中会出现如下问题,这个报错第一眼看着挺懵逼的:
Idea 2022.1.3 版本就好很多,报错是人话了:
java: package sun.util.locale is not visible (package sun.util.locale is declared in module java.base, which does not export it)
排查
如果对于Java9的模块化有一丁点概念,基本这个问题都能迎刃而解,但是如果像我一样不懂的话,大概会在这个问题上卡上一段时间,并且谷歌也查不出直接关联的情况,不过查类似报错会跟你讲模块化的事情。
思考
关键的灵感来自于下面这篇文章,个人按照文章的思路,先把整个项目从maven到项目整个配置使用的统一JDK版本,所以索性全换成JDK11尝试。
intellij idea - Error: java: invalid source release 1.9 - Stack Overflow
此外还参阅了文章: (1) java9迁移注意事项_个人文章 - SegmentFault 思否 ,这篇文章中介绍了迁移到高版本JDK之前建议先到jdk.1.9 转为模块化之后再往更高版本升级。 但从IDEA的默认下载的JDK在新版本中只有9、11 - 17 这几个大版本了,所以就没有尝试了。个人也建议先到JDK9的模块化先弄一遍再去升级。
先把整个Compiler项目的版本换成JDK 11,这个页面比较重要后续还会在用到:
在RocketMq的pom.xml
当中把编译版本改为11。
保险期间,利用 ctrl + shift + F
的快捷键把所有有可能指定的地方全改了。
最后就是项目本身的版本了:
这样一通配置之后,发现还是会报同样的错,所以可以确定是模块化的问题,但是问题是我在编译的时候如何加参数?
这里不再讨论JDK1.9 的模块化细节(足够新写几篇文章介绍),这里介绍解决办法,介绍Idea如何配置编译参数。
Idea 如何添加编译参数?
Setting -> Build, Execution -> Java Compiler
最下方有关键词 compiler paramter:
这里吐槽一下Idea的反智操作逻辑:修改完参数之后,你先去别的可输入框先点一下,然后Aplly按钮会亮起来告诉你有改动过,建议先确定能否Apply,先Apply再点OK。否则容易改了参数一个OK最后发现修改无效。
store 子项目编译参数设置为:
--add-exports java.base/sun.nio.ch=ALL-UNNAMED
test 子项目的编译参数设置为:
--add-exports java.base/sun.util.locale=ALL-UNNAMED
加入之后按IDEA 右上角的小锤子编译一下,这个小问题圆满解决。
小结
长期JDK8选手,工作也不不允许用JDK8更高的版本,外加外部设施对于高JDK版本支持度不够,比如JDK11的Jenkins就有问题。
真实照应了[[How to Upgrade from Java 8 to Java 17]]里面的原文评论:
- From my experience, the biggest issue is not the code itself, but the surrounding infrastructure(周边设施). For example replacing Jenkins plugins that don't support Java 11 was painful.
- The biggest issue in my experience migrating java apps from version 8 it's related with java time precission:
真的只能期待一些周围开源组件强制要求用户使用高版本JDK才有可能推进了。
写到最后
不能当JDK8忠实粉丝,还是得与时俱进,与时俱进.....见到熟悉的提醒界面非常安心。