尤其是一些客戶端開發(fā)的,java8又大(無法用jlink剪裁溃肪,runtime是java 11+做出來的幾倍大)免胃,各種特性又少,無論是java core還是javafx惫撰,都在最新幾個版本中大幅提升性能和特性羔沙,為什么還有那么多人執(zhí)著于java 8?
2018年我有一大部分工作都在和Java 9 作斗爭厨钻!Java 9是2017年9月發(fā)布的扼雏,而我們一直到2018年9月——花了整整一年的時間——才切換到Java 9,又花了三個月的時間切換到Java 11夯膀。
反觀JetBrains诗充,似乎花了兩年多才把runtime升級到11(假設(shè)他們是從Java 9一發(fā)布就升了),我們和JB的代碼規(guī)模差不多诱建,都是百萬級別的蝴蜓,現(xiàn)在你應(yīng)該對升級這事的周期有一個基本的認(rèn)識了吧?
總結(jié)一下,就是Java 9各種奇怪的改變+業(yè)界長久積累的庫中的瞎JB用法導(dǎo)致了大部分項目被迫停在Java 8上茎匠。我強(qiáng)烈建議把題目改成「為什么還有那么多人被迫使用Java 8」格仲,因為,這真的是客觀原因啊诵冒。
我舉幾個栗子讓你們看看遷Java 9/11這件事情有多蛋疼凯肋,算是給想遷移的你們提前打個預(yù)防針。
Java 9之前汽馋,Java的版本號用的是這個標(biāo)準(zhǔn)侮东,也就是我們常見的1.8.0_213這種字符串。 Java 9之后豹芯,大家一拍大腿悄雅,反正已經(jīng)做了這么多改變,不差這一個告组!來人懊何啊!給我把這個版本號字符串換掉木缝!于是有了JEP223,一個山寨版的語義化版本號围辙,從此以后我碟,版本號大概長這個樣子:9.0.0.4。平心而論姚建,這個變更是非常必要的矫俺,但是一眾依賴以前的版本號字符串的庫就都哭了……誰能想到你丫的連這種東西都變啊。
(據(jù)說當(dāng)年還有人提議以后Java的版本號跟業(yè)界保持一致掸冤,用18.1/19.1之類的年份+次序命名 厘托,后來就沒聲音了,應(yīng)該是被打死了稿湿。)
那些廣為人知的大庫還好說铅匹,改的還算及時,一些小作坊生產(chǎn)的三無庫就慘了饺藤,一調(diào)用就給你丟個Illegal version number 9.0.0.4出來包斑, 還找不到人修,來來來你說咋辦涕俗?
Java 8之前對反射沒有限制罗丰,只要setAccessible(true),你連JVM的底褲都可以掀掉再姑。我們都知道萌抵,一旦給用戶自由,用戶就會瞎JB用。大家都知道JVM初始化的時候傳進(jìn)來的環(huán)境變量是不可變的绍填,存在ProcessEnvironment的一個不可變Map里霎桅。但是沒關(guān)系,我有反射啊……
其他的栗子還包括沐兰,通過反射調(diào)用各種私有的API……在你升級之前哆档,你永遠(yuǎn)不知道有多少地方在用這種鬼鬼祟祟的操作……升級就好像你面前的一條康莊大道,你開開心心地踏上去準(zhǔn)備走住闯,咚瓜浸!一個地雷炸了!piaji比原!你掉坑里了插佛!二十米的路你走了三個月!黑著臉從坑里爬出來量窘,瞅瞅前面……這特么還有多少個地雷在等著我啊……在爆炸之前你永遠(yuǎn)不知道到底有多少庫在用反射偷偷摸摸調(diào)私有API雇寇,我管它叫薛定諤的反射
還有最常用的一個操作叫做defineClass,用來把魔改后的字節(jié)碼注入ClassLoader蚌铜。ClassLoader的這個方法是protected的锨侯,沒關(guān)系,我們有反射啊……另外一些小伙伴直接用反射調(diào)用Unsafe.defineClass——看名字你就知道有多不安全冬殃,Java 11之后這個方法直接被干掉了囚痴。
能用到這些方法的庫通常都是大廠生產(chǎn)的有售后的庫,所以通常都能得到很好的解決审葬。但是緊接著問題就來了——你把一個庫從2011年的版本直接升到了2018年的版本深滚,你心里慌不慌?
更別提有些小作坊的庫偷偷摸摸地從褲襠里掏出來一個Unsafe.defineClas
在升Java 9成功之后涣觉,懷抱著升級成功的竊喜痴荐,我們又趁熱打鐵想升Java 10。然后碰到了IDEA的一個bug:IDEA錯誤地理解了一個還未生效的草案JEP182官册,編譯器給出了不正確的結(jié)果生兆,我花了一上午時間調(diào)試IDEA的源代碼才發(fā)現(xiàn)是IDEA的鍋。IDEA尚且如此攀隔,其他項目碰到兼容性問題皂贩,真的只是時間問題。
業(yè)界的很多工具不支持Java 9昆汹,最廣為人知的應(yīng)該是FindBugs了明刷。還好,它還算后繼有人满粗,SpotBugs挑起了它的大梁辈末,那些小作坊庫可就慘了,過去的十年是Java生態(tài)系統(tǒng)迅猛發(fā)展的十年,你的項目只要沾到一點(diǎn)“在自己的代碼里瞎JB使用Java 8/斷言自己使用的是Java 8”的庫挤聘,可能就要花上幾天時間去調(diào)試轰枝、去嘗試解決。
最后组去,最重要的一點(diǎn)是鞍陨,我們的代碼是有嚴(yán)格的自動化測試覆蓋的,所以我們在升級之后能非常有底氣地說我們升級成功了从隆!對于沒有測試覆蓋的祖?zhèn)鞔a诚撵,你升級完事,跑一下键闺,似乎沒問題寿烟,但是真的沒問題么?去問老天爺吧……沒有完善的測試覆蓋的項目請勿輕易嘗試辛燥。
其實升級不是什么非常困難的事情筛武,主要是費(fèi)時費(fèi)力,收益可能卻沒有那么明顯挎塌。對于一個成熟的公司來說徘六,代碼只是輔助業(yè)務(wù)的手段,而非目的榴都。如果沒有十分的利益保證硕噩,別說升級,連bug都是可以不修的缭贡。就這樣。