發表日期 3/6/2022, 10:21:11 AM
作者|Steve Hannah
譯者|核子可樂
編輯|燕珊
Java 不適閤編寫桌麵應用,這是事實還是偏見?
本文作者以個人視角對 Java 桌麵發展曆程做瞭迴顧,內容來自他在上世紀九十年代後期擔任 Java 開發者時的所見所感,主要講述曾經的“殺手級”桌麵語言 Java 是為何從 21 世紀開始頹勢盡顯、步入衰落的。值得一提的是,作者如今在做一款開發者友好型 Java 桌麵部署工具(jDeploy),其實他還是希望 Java 可以重拾風采,再度變得對桌麵開發具有吸引力。
我的大學時代正好趕上 2000 年之前的最後那幾年,當時 Java 是計算科學專業裏的官方語言。雖然也有幾門課程要求使用 C 和 C++,但所有基礎知識教學都是圍繞 Java 語言來設計的。為瞭防止有讀者朋友較真,我再說得更準確些:這些課程會用 Java 語言來教學,不是說隻教 Java。
其實大學的計算機科學課並不教授特定的編程語言,教學內容主要是相關概念,再使用時下流行的編程語言來演示這些概念,所以學生們得拿齣課餘時間掌握編程語言。也有些課程要求更嚴格,比如“這份作業必須使用 Java 完成”,但大多數高級課程就不再做此限製,大傢想用什麼語言就用什麼語言。(有些作業需要使用特定的庫或者編程語言。我還記得有一份作業就是用 pthreads 庫為操作係統分配綫程,相當於強製使用 C 語言。)
我上大學那會,對 Java 的認知還僅限於 Applet。我既不清楚 Java 在行業裏是什麼地位,也不知道它跟其他編程語言相比到底有什麼優勢。而且越是深入學習,我就越覺得 Java 這東西有點名不副實――它更像是種玩具語言,畢竟那些“真正”的嚴肅開發都是用 C++ 這類語言實現的。反正係裏總有一幫故作深沉、頭發鬍子一大把的傢夥,總愛吹噓跟 C++ 一比、Java 屁都不是。
Java 很慢
他們倒也不是鬍攪蠻纏,最常見的理由就是“Java 很慢”。相信任何用過 Java GUI 應用程序或者包含 Java Applet 網頁的朋友都同意這個觀點。那時候用 Java 編寫的桌麵應用程序就隻有開發工具,我能想起的就是 ArgoUML 和 NetBeans,它們確實不好用而且速度很慢。那種慢,就像是雙腳陷進瞭泥潭――無論是上下滾動還是打開菜單,所有操作都有“粘粘”的延遲。
但支持 Java 的教授們則堅持認為,隻要配閤即時編譯,Java 也是可以快起來的。而且在編譯瞭代碼路徑之後,“理論上”它的運行速度可以追平甚至超越 C++。但我們這幫學生根本不買賬,單純覺得他們是在嘴硬。
Java 應用程序不是“真正的”應用程序
另一個讓人感覺 Java“不上檔次”的原因,在於我們開發的應用程序都不是本機應用程序。Java 構建的應用程序隻是一堆.class 文件的集閤;哪怕再“高階”一點,生成的.jar 文件也隻能在安裝瞭 Java 的計算機上運行。相比之下,其他學校的朋友們展示的項目就洋氣多瞭,這些可是貨真價實的可執行文件――雙擊之後,它們就像真正的專業應用程序那樣開跑,有程序容器、也有屏幕頂端菜單,這纔像話嘛。
我記得自己問過一位教授關於 Java 能不能生成本機可執行文件,他的迴答是“為什麼非得這樣?生成本機可執行文件,Java 的跨平台優勢不就沒瞭嗎?”
如果真的想把應用程序部署成桌麵程序,他建議我研究研究 Java WebStart。這樣不用本機程序包,Mac 和 Windows 用戶也能順利安裝我的應用程序。WebStart 聽起來挺有搞頭,但我還是覺得跟自己的真正目標不太相符。畢竟就算可以用 WebStart 分發應用程序,用戶也仍然需要事先安裝 Java。我承認,當時已經是 2001 年,大多數計算機都預裝瞭 Java。但跟直接雙擊就能打開,這種體驗仍然不夠好。
另外,在親自嘗試瞭一些 WebStart 應用程序之後,我發現它的錶現也就那樣。應用程序的打開速度還是慢,因為啓動後需要先下載更新;這些程序也沒有被正確集成到操作係統當中。雖然 WebStart 也提供在桌麵上為應用程序保存執行彆名的功能,但效果不好。
我相信那時候肯定已經有第三方工具能把 Java 應用程序成本機可執行文件,但不光會占用大量資源、而且絕對“隻支持 Windows”。我也關注過 GCJ,這款 Java GNU 編譯器宣稱能把 Java 編譯成機器碼。但它隻適用於 API 子集而且不支持 Swing――所以用戶就隻有兩個選項,要麼使用本機 GUI 工具包、要麼乾脆不要 GUI。
所以我心裏有瞭答案:至少在當時,Java 桌麵開發已經是死路一條,唯一的用處就是寫點小程序――問題是跟 Flash 這類更輕、更快的技術相比,Java Applet 的優勢其實也已經不明顯瞭。
Applets:殺手級應用
雖然我這份“編年史”沒那麼詳盡,但要談 Java 在桌麵端的發展曆程,殺手級應用 Applets 肯定是個繞不開的話題。
Applets 在 1995 年那會確實頗具開創性,它們首次讓用戶在網頁之內看到瞭交互式的 2D 圖形與動畫。最初(Java 1.0 時代),Java 解釋器是被內置在瀏覽器當中的;但不久之後,就改為通過插件調用係統中已經安裝的 Java 運行時。
最早的小程序嵌入起來非常簡單,直接把.jar 或者.class 文件上傳到 Web 服務器、再嚮網頁中添加標記就行。遺憾的是,這種便捷性很快就消失瞭。隨著 Java 新版本的發布和 IE 瀏覽器的齣現,嵌入小程序所需要的 HTML 代碼越來越復雜,需要針對不同的瀏覽器和 Java 版本使用不同的標簽。雖然標簽號稱可以在“多瀏覽器”環境下正常嵌入小程序,但 IE 上實際使用的卻是標簽,而 Mozilla 上使用的則是標簽。
於是之前的嵌入方法
就慢慢變成瞭:
直到 Java 1.3 版本,小程序的用戶體驗都非常糟糕,以至於 Applet 隻能在係統管理員完全可控的客戶端軟件環境中纔能使用。於是乎,靠 Java Applet 在網頁中添加簡單交互的計劃基本破産。
時間快進到 2001 年,小程序的生命基本走到瞭終點。Flash 憑藉著更簡、更輕便、更快捷,取代 Java Applet 成為瀏覽器媒體交互的業界標準,也獲得瞭更廣泛的安裝基礎(我記得當時 99% 的計算機都安裝瞭 Flash)。
不止如此,小程序還大大敗壞瞭 Java 的名聲,其中很多安全漏洞都被宣傳成“Java 漏洞”。這就給人留下一種錯誤印象,即任何用 Java 編寫的東西都是潛在的安全威脅――雖然實際上這些“漏洞”隻是小程序自己的問題。盡管之後很多年仍時不時能看到 Java 小程序的身影,但它在人們心中早已成瞭過時技術的代名詞。
我一直覺得 Applets 算不上可行的桌麵應用程序發布方式,但它能經久不衰、肯定也有自己的獨到之處。
GUI 工具包:AWT、Swing 與 SWT
我剛開始使用 Java 那會,它的初始 GUI 工具包 AWT(Abstract Windowing Toolkit) 已經有點過時瞭,倒是新的“輕量級”工具包 Swing 得到瞭人們的青睞。簡單來講,AWT 屬於“重量級”工具包,提供的是 用於處理本機小部件的 API。重量級 UI 庫的問題在於難以維護,而且受到底層平台可用組件的限製。相比之下,Swing 則擁有輕量化優勢,能夠繪製自己的一組小部件、降低瞭維護難度,幫助用戶輕鬆繪製齣自己的跨平台界麵。
Swing 提供可插入 UI,支持樣式設置以模擬本機平台的外觀。所以在 Mac 上運行時,Swing UI 的觀感與 Cocoa 等本機應用程序完全相同;而在 Windows 上運行時,觀感又高度接近 Windows。此外,Swing 還允許自定義外觀,讓程序的使用體驗脫離任何操作係統平台。總之,這是一款靈活的 UI 解決方案。
但在 2000 年初的計算機上,Swing 界麵也是齣瞭名的資源殺手。我自己有一台半透明藍色的 iMac,它搭載的 233 MHz 芯片幾乎運行不瞭 NetBeans。我爸爸的 G4 電腦搭載 400 MHz 處理器,性能倒是更強一些,但整個運行體驗仍然勉勉強強、湊湊閤閤。
所以在當時,用 Java 構建 GUI 要求人們對摩爾定律抱有極大的信心――雖然當下的運行錶現不好,但再過幾年應該會有起色。
時間來到 2022 年,一天室友嚮我推薦瞭 Eclipse 與 SWT――這是一套似乎能夠解決性能問題的 Java GUI 開發替代方案。Eclipse 使用的是 SWT(Standard Widget Toolkit),一款新的“重量級”Java UI 工具包,但響應速度明顯要比使用 Swing 進行構建的 NetBeans 更快。所以乍看之下,長久的難題似乎終於有瞭答案。
SWT 的優勢在於無需自行繪製小部件,而僅僅是為瞭平台的本機小部件提供綁定,因此由它構建的應用程序在觀感上原生度更高、響應速度也更快。但經曆過 AWT 的糟糕體驗,我仍然保持著警惕。既然 Sun 公司的聰明人都覺得輕量化纔是正確的道路,為什麼 IBM 這邊拿齣的是重量級工具包呢?
而且我對 SWT 的興奮也沒持續多久。Eclipse 雖然比 NetBeans 響應更快,但用起來仍然有種笨拙的感覺,完全達不到本機應用的水平。倒是 Swing,雖然速度還是更慢,但一直隨著新版本的發布而不斷改善。根據 AWT 與 Swing 相關書籍、論壇和博文的數量,我估計 Swing 社區的規模比 SWT 大得多。Swing/AWT 曾經是、現在也仍然是 Java 中內置的唯一工具包,能夠確保開發者無需任何第三方依賴項、單憑 Java 運行時環境就構建起完整的 GUI 應用程序。
雖然我還沒有在項目中實際使用過 SWT,但很高興看到它能經受住這麼多年的風雨考驗。期間先後齣現過不少不支持 Swing 的 JVM(Avian 就是其中一種精簡型 AOT(預先)編譯器,它不支持 Swing、但提供使用 SWT 的 GUI 演示),靠的就是 SWT 這個能在 Java 平台上快速編寫 GUI 應用程序的解決方案。
據我所知,2000 年初那會的跨平台 Java GUI 開發市場就是由 AWT、Swing 和 SWT 這三傢主導。Java FX 直到 2007 年纔齣現。
Java Cocoa 應用
還是在 2000 年初,蘋果突然宣布要把 Java 作為 Mac OS X 上的首選編程語言。Java 被預裝在 OS X 當中,Swing 也獲得瞭本機 Mac 主題,使其觀感高度接近於本機應用程序。這意味著大傢完全可以將 Java 應用程序直接發布給 Mac 用戶,代碼一定能在機器上運行起來、而且提供與本機係統相匹配的觀感體驗。
他們還推齣能將 Java 應用程序打包成本機 OS X.app 的工具,所以開發者就能把 Java 應用程序像真正的本機應用那樣交付給用戶。如果認真遵循 Mac 用戶界麵指南,使用者甚至感受不到這款應用程序是用 Java 編寫的。
遺憾的是,大多數 Swing 應用程序的開發者並沒有遵循 Mac UI 指南,所以用戶在使用 Java 應用程序還是能感覺到事情“不太對勁”。比如應用程序可能在菜單項中使用瞭錯誤的加速鍵、甚至不提供標準菜單。沒錯,雖然聽起來很簡單,但想讓 Swing UI 在 Mac 上完全適配本機風格還是頗有難度。這裏我們用 Mac UI 的本機工具包 Cocoa 來對比:Cocoa 提供的是完全原生的應用程序外殼,並且以菜單為起點;但 Swing 應用程序則是從零開始。開發者必須自行創建窗口和菜單,除非直接套用框架――但我從沒見過能純原生 Mac 應用程序體驗的 Java 框架。
但蘋果總有辦法,他們更進一步、為 Coca 提供瞭 Java 綁定包。如此一來,我們的 Java 應用程序不僅看起來更像是本機應用程序,實際上也成瞭本機應用程序。我們隻需要在 Xcode 中創建一個新的 Cocoa 項目,再選擇 Java 作為項目語言即可。它會為大傢提供漂亮的本機應用程序外殼作為設計起點,而在按下“Build”鍵時,生成的將是一個可以直接發送給用戶的純本機應用程序。我也用 Cocoa 試著編寫過示例應用程序,效果非常完美。但即便錶現齣色,它在行業中也仍然不受待見。因為這類應用程序隻適用於 Mac,畢竟用的是 Mac 上的專有 UI,所以 Java 社區裏“一次編寫、隨處運行(WORA)”的狂熱支持者們對 Cocoa 嗤之以鼻。另一方麵,“原生”Mac 開發社區則對 Java 不感興趣,所以相關文檔很少。而且要實現從 Cocoa 到 Java 的對接,開發者必須能熟練地將 Objective-C 代碼轉換成 Java 中的等價錶示――相當纍人。
所以不齣所料,蘋果在幾年之後的 2005 年就放棄瞭 Cocoa-Java 項目。而且齣於種種原因,蘋果對 Java 的興趣也很快淡去。我記得當時史蒂夫・喬布斯還有句名言,“Java 如同開發者的鐐銬”。他說得一點兒沒錯。
如果大傢也想試試用 Java 編寫 Cocoa 應用程序,請關注 Rococoa 項目。作為 Cocoa-Java 理想的繼任者,它目前仍處於活躍狀態。
這讓我們何去何從
我的這份“編年史”既不全麵、也不完全遵照時間順序。我講述的是自己在 Java 桌麵環境上的真實經曆,而且主要偏嚮 Mac 一側(因為傢裏的第一台計算機是蘋果 IIGS,我爸後來又買瞭台 Mac Classic)。
所以結閤個人經曆,2005 年可以說是 Java 語言在桌麵環境中的發展轉摺點。在 2005 年之前,網絡論壇上有著大量關於 Java 桌麵技術的問答內容,例如 Swing、Cocoa Bridge 等。但到 2005 年之後,相關內容快速減少。那 2005 年前後到底發生瞭什麼重大轉變?Java 桌麵開發者們又跑到哪裏去瞭?我猜大部分開發者可能轉嚮瞭服務器端,而繼續堅守客戶端的開發者也許是轉嚮瞭 Web 或者本地開發方麵。
如果您也經曆過這段曆史,不妨在評論中聊聊自己的體會和迴憶。也許擁有不同背景、不同職業生涯的開發者會有不一樣的觀察角度。
https://jdeploy.substack.com/p/the-decline-and-fall-of-java-on-the?s=r