JPMS模組對於庫包開發人員的負面效應
Java 8可能是有史以來最成功的Java版本,它被廣泛使用,因此,幾乎所有開源庫都在Java 8上執行。
Java 9於2017年9月釋出,但它不是一個會連續支援多年的版本,相反,它只有六個月的生命週期,現在已經過時了,因為Java 10都已經被淘汰了,在以後六個月的時間裡,Java 11將會淘汰Java 10等等。
但幸運的是,Java 11將是一個“長期支援”(LTS)版本,具有幾年的安全性和錯誤支援(Java 8也是LTS版本),因此,即使Java 10已經淘汰,Java 8仍然是開源庫開發人員目前正確定位的合理Java版本,因為它是當前的LTS版本。
但是當Java 11出現時會發生什麼?由於Java 8在Java 11釋出後不久將不再受支援,因此合理的升級路徑應該是11,不幸的是,迅速轉移到Java 11可能存在風險。
模組路徑
首先了解一下類路徑和模組路徑之間的區別,類路徑仍然存在於Java 9+中,以和Java8相同的方式工作。
模組路徑則是新的,當jar檔案位於模組路徑上時,任何module-info都會用於更嚴格的JPMS規則,例如,一個public方法不再可呼叫,除非它被明確配置為exported。
升級以後,需要將舊的非模組化jar檔案放在類路徑class-path上,同時將新的模組化jar檔案放在模組路徑module-path上,然而,沒有人可以強制你執行,這就帶來會造成混亂的情況,有四種可能性:
1. 在模組路徑上的放置你的模組化後的jar包
2. 在類路徑上的放置你的模組化jar包
3. 在模組路徑上的放置非模組化jar包
4. 在類路徑上的放置非模組化jar包
為確保你的庫包正常工作,需要在類路徑和模組路徑上進行測試。例如,與類路徑相比,模組路徑上的服務載入非常不同。一些資源查詢方法也完全不同。
進一步複雜化的是,JPMS沒有明確支援測試,為了測試模組路徑上的模組(這是一個緊密鎖定的軟體包集),必須使用--patch-module 命令列標誌,此標誌有效地擴充套件了模組,將測試包新增到與測試類相同的模組中,(如果你只測試公共API,你可以在不使用補丁模組的情況下執行此操作,但是在Maven中你需要一個全新的專案和pom.xml來實現這種方法,可能很少見。)
在最新的Maven surefire外掛(v2.21.0及更高版本)中,使用了patch-module標誌,但如果你的模組具有可選的依賴項,或者您有其他測試依賴項,則可能必須手動新增它們。
鑑於這種情況,開源庫包開發人員應該做些什麼?
選項1,什麼都不做
在大多數情況下,在Java 8或更早版本上編譯的程式碼在Java 9+的類路徑上執行得很好,所以,你可以什麼都不做,忽略了JPMS。
問題是如果有其他專案將取決於你的庫,如果不採用JPMS,你會間接阻止這些專案的模組化。(一旦專案的所有依賴關係都被模組化,整個專案才能完全模組化。)
當然,如果你的程式碼不能在Java 9+上執行,比如已經使用了sun.misc.Unsafe,那麼還需要解決其他問題。
並且不要忘記使用者如果將jar檔案放在class-path或module-path上。你可能需要有兩個測試。
選項2,新增模組名稱
Java 9+能識別MANIFEST.MF檔案中的新條目,Automatic-Module-Name條目允許jar檔案宣告其名稱,可如果它想轉為的模組化jar檔案時可以使用,以下是如何使用Maven新增它:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestEntries> <Automatic-Module-Name>org.foo.bar</Automatic-Module-Name> </manifestEntries> </archive> </configuration> </plugin> <p class="indent"> |
這是一個很好的簡單方法,它保留模組名稱,並允許依賴於jar檔案的其他專案完全模組化,如果他們願意。
但由於它如此簡單,很容易忘記測試方面,同樣,jar檔案可能還會放在類路徑或模組路徑上,兩者的行為可能完全不同,事實上,現在它有一些模組資訊,工具可能會以不同的方式對待它。
當Maven看到Automatic-Module-Name它時,它通常將其放在模組路徑而不是類路徑上,這樣可能反而沒有任何效果,達不到我們使用這個選項的目的;或者它可能會顯示你的程式碼在類路徑上可工作,但在模組路徑上不工作的錯誤。
現在使用Maven,必須使用surefire外掛v2.20.1來測試類路徑(一個不知道模組路徑的舊版本),要在模組路徑上進行測試,請使用v2.21.0,在這兩個版本之間進行切換當然需要一個手動過程。
選項3,新增module-info.java
這是關於JPMS的眾多網頁和教程中描述的完全模組化方法。
module org.foo.bar { requires org.threeten.extra; exports org.foo.bar; exports org.foo.bar.util; } <p class="indent"> |
那麼,這對開源專案有什麼影響呢?
與選項2不同,你的程式碼現在為Java 9+準備好了,Java 8編譯器卻無法理解該檔案。我們真正想要的是一個包含Java 8類檔案的jar檔案,但module-info.java只包含在Java 9+下編譯的檔案,理論上,在Java 8上執行時,module-info.class檔案將被忽略。
Maven有一種技術可以實現這一目標。雖然這項技術運作良好,但事實證明這遠遠不足以實現目標,要實際獲取適用於Java 8和9+的單個jar檔案,需要:
1. 使用Java 9+上的釋出一個微構建Java 8的標識
2. 新增一個OSGi,實現功能過濾器,讓它仍然與Java 8相容
3. 在Java 8上構建時,從maven-javadoc-plugin中排除module-info.java
4. 使用maven-javadoc-plugin v3.0.0-M1,手動將依賴項複製到目錄,並使用其他Javadoc命令列引數引用它們。
5. 從maven-checkstyle-plugin中排除module-info.java
6. 從maven-pmd-plugin中排除module-info.java
7. 手動交換maven-surefire-plugin的版本來測試模組路徑和類路徑
整合 Java 9 之後,程式碼可能會從650行增加到862行,增加了很多複雜性,包括配置檔案和變通方法。
升級Java9+以後,你的專案可能再也不能被Android使用了(因為這個團隊似乎在新增一個簡單的“忽略模組資訊”規則方面動作很慢);許多使用舊版位元組碼庫(如ASM)的工具也會失敗 - 我有一個報告稱特定版本的Tomcat / TomEE無法載入模組化jar檔案,我最終不得不釋出一個“舊的”的非模組化jar檔案來應對這些情況,這是非常令人沮喪的。
雖然我已經新增module-info.java到了一些專案,但我不能推薦其他人這樣做 - 這是一個非常痛苦和耗時的過程。考慮它的時間似乎是等Java 11或更高版本被廣泛採用時。
總結
截至今天,JPMS對庫包釋出者來說是一種痛苦,模組路徑與類路徑的分離是問題的核心。如果沒有在模組路徑和類路徑上進行測試,你真的無法釋出一個庫包 - 有一些細微的角落情況,環境不同。
相關文章
- Java模組系統JPMS是巨坑?- jodastephenJavaAST
- 軟體開發人員的關鍵績效指標指標
- 測試人員對績效考核改革的疑惑
- Python中的包模組引用成員的方法Python
- 路人開發對測試人員的看法
- 雷達模組開發學習教程(一)——檢測人員資訊
- 每個開發人員都應該知道的 10 個 GitHub 倉庫Github
- 如何對技術人員進行績效考核?
- 基於Laravel5.5的模組化開發Laravel
- 面對國內的低程式碼開發平臺,開發人員和企業該如何選擇?
- 6種適用於開發人員的Linux發行版本!Linux
- [開發故事]關於測試人員的職業發展
- 開發人員使用遺留程式碼庫指南
- 軟體測試初級人員如何應對職場面試?面試
- 對於JS模組的簡單瞭解JS
- Rust 程式設計影片教程對應講解內容-包、crate、模組Rust程式設計
- 開發人員應該害怕低程式碼嗎?
- Python開發常用的庫及模組!Python學習教程Python
- 模組化開發靜態資源對映
- duxapp:基於Taro使用模組化開發,提升開發效率UXAPP
- 基於ngx_lua模組的waf開發實踐
- MySQL內部開發人員如何看待MySQL組複製?MySql
- 模組和包
- Python - 模組包Python
- 模組與包
- 適用於 PHP 開發人員的 Python 基礎知識PHPPython
- Substrate 區塊鏈應用開發之存證模組的功能開發區塊鏈
- [譯] 優秀 JavaScript 開發人員應掌握的 9 個技巧JavaScript
- Android開發人員應該知道的一些技術Android
- 新幹貨:開發人員都應該知道的CLI命令
- 每個開發人員都應該知道的WebSockets知識Web
- Rust 程式設計視訊教程對應講解內容-包、crate、模組Rust程式設計
- 15個對開發人員最佳的Chrome擴充套件外掛Chrome套件
- 為什麼 Python 開發人員應該使用 PipenvPython
- Linux系統對於實施人員的價值Linux
- 面對玩家差評,製作組應該如何應對?
- 藉助Gradle Plugin解決模組化開發中模組如何對外暴露介面GradlePlugin
- 測試人員與開發人員的比例究竟多少是合理的?