02.03 夯實基礎:如何構建一個既模塊化又兼容Java 9之前版本的庫呢?

原文:https://www.jdon.com/50895

如果您是庫包或框架的作者,你可能希望看到你的庫包在大量應用程序中使用。提升庫包使用量的一種方法是使其與舊版Java兼容。同時,你可以考慮對庫進行模塊化,以使其對充分利用Java平臺模塊系統(JPMS)的應用程序具有吸引力。

但是,JPMS僅由Java 9和更新版本實現。那麼,如何在9之前構建一個既模塊化又兼容Java版本的庫呢?

模塊化jar只是一個普通的jar,它包含一個module-info.class代表模塊描述符的文件。通常通過編譯相應的module-info.java文件來生成該模塊描述符。

在Java 8及更早版本上運行時,將忽略模塊描述符,因為module-info不是它的合法的Java標識符。這意味著可以通過為目標庫的版本創建普通jar並在其中插入模塊描述符來生成與Java 9之前版本兼容的模塊化jar。

執行這樣的辦法的標準方法意味著調用java編譯器兩次:

  • 編譯所有源,除了module-info.java使用適當的javac標記參數才能提供Java 9之前版本的兼容性。
  • 使用Java編譯器9+編譯module-info.java。

Maven

Maven 描述 了一種符合上述策略的構建方法。

另一種解決方案是

ModiTect ,一個用於Java 9模塊系統的Maven插件。ModiTect提供的目標之一是add-module-info,它允許您將模塊描述符添加到當前Maven項目生成的JAR中:

<plugin>
<groupid>org.moditect/<groupid>
<artifactid>moditect-maven-plugin/<artifactid>
<version>1.0.0.Beta1/<version>
<executions>
<execution>
add-module-infos
<phase>package/<phase>
<goals>
<goal>add-module-info/<goal>
/<goals>
<configuration>
<jvmversion>11/<jvmversion>
<module>
<moduleinfofile>
${basedir}/src/main/java/module-info.java
/<moduleinfofile>
/<module>
/<configuration>
/<execution>
/<executions>
/<plugin>

ModiTect使用一種聰明的技術來創建模塊描述符,而無需Java編譯器。它使用 JavaParser 分析module-info.java文件,並使用 ASM 字節碼操作框架生成相應的模塊描述符。這樣,即使您使用Java 9之前的編譯器,它也允許您創建模塊化jar。

Gradle

從ModiTect的方法中汲取靈感,我實現了一個 Gradle插件, 用於創建面向Java 8或更早版本的模塊化jar。

使用這個插件非常簡單:build.gradle只需要添加插件並指定庫所針對的Java版本:

plugins {
id 'java'
id 'org.beryx.jar' version '1.0.0'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8

將module-info.java文件放在src/main/java項目目錄中後,您可以使用以下命令構建模塊化jar:

./gradlew jar

不需要Java 9+編譯器來構建模塊化jar,因為該插件使用與ModiTect相同的技術。但是,請記住,此技術無法檢查模塊描述符的有效性。指向不存在的包,模塊,服務或服務實現將不會被發現。

因此,強烈建議通過使用Java 9+編譯器和sourceCompatibility與targetCompatibility設置進行額外構建項目來驗證模塊描述符,好消息是您不需要更改構建腳本來執行此操作。該插件允許您通過設置項目屬性來覆蓋sourceCompatibility和targetCompatibility值javaCompatibility:

./gradlew -PjavaCompatibility=9 jar

請注意,此項目屬性會使用相同的值覆蓋兩者sourceCompatibility並targetCompatibility

如果插件檢測到至少有一個sourceCompatibility並且targetCompatibility有效值> = 9,它會自動應用 Chainsaw 插件,這會增加對JPMS的支持。這就是為什麼在Java 9+兼容模式下運行時,構建腳本不需要進行任何更改。


分享到:


相關文章: