引言
簡單記錄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忠實粉絲,還是得與時俱進,與時俱進.....見到熟悉的提醒界面非常安心。