歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Oracle 發布 Java 模塊系統狀態報告

Oracle 發布 Java 模塊系統狀態報告

日期:2017/3/1 9:20:54   编辑:Linux編程

Oracle Java平台組首席架構師Mark Reinhold發表了一份關於模塊化系統的情況的報告,強調了模塊化的目標是什麼。由於和已經存在的框架存在明顯的重復,特別是OSGi,報告引起發了人們的討論。

正如報告中所解釋的,以及在JSR-376和模塊化系統項目主頁中完整的詳細說明,模塊化系統是為了解決當前Java訪問模型中的兩個疏漏:

  • 可靠的配置:當前一個組件通過類路徑訪問另一個組件的類時相當容易出錯,特別是嘗試使用不在類路徑裡面或者存在多個版本的類的時候。
  • 強封裝:沒有辦法去限制特定組件暴露給其他組件的類,外部能訪問所有的公共類。

完整的細節能夠在報告和InfoQ之前的文章中找到,總的來說,每一個組件通常(但不一定)作為一個jar文件,其中包含了如下結構的模塊描述文件module-info.java:

module com.foo.bar {

requires com.foo.baz;

exports com.foo.bar.alpha;

exports com.foo.bar.beta;

}

文件結構中包含一行或多行exports用於指出能夠被其他組件訪問的包,零行或多行requires用於指出自身需要訪問的其他模塊。該系統提供 了方法用於在編譯時評估訪問類型是否具有正確的可見性(例如聲明為公共類並被所需組件導出),並在運行時評估必需的模塊是否可用,而不需要去檢查完整的類 路徑。類似於OSGi中的清單文件。

OSGi的背景

OSGi是一個基於Java的模塊化系統和服務化平台,實現了一個完整的動態的組件模型。從1998年在JSR-8第一次提出,在隨後的審核中被延 遲發布(最近一次是2014年),OSGi定義了bundle(類似模塊),采用包含如下的MANIFEST.MF文件的JAR文件的形式:

Bundle-Name: Hello World

Bundle-SymbolicName: org.wikipedia.helloworld

Bundle-Description: A Hello World bundle

Bundle-ManifestVersion: 2

Bundle-Version: 1.0.0

Bundle-Activator: org.wikipedia.Activator

Export-Package: org.wikipedia.helloworld;version="1.0.0"

Import-Package: org.osgi.framework;version="1.3.0"

(例子來源於Wikipedia)

顯而易見的,盡管格式不一樣,但是目的表現的和Java模塊系統很相似。的確,Java平台模塊系統和OSGi之間的相似性,在2005年提出的 JSR-277,“Java模塊系統”中,初次嘗試模塊化Java時就已經被注意到了。最初瞄准的Java 7,JSR-277專注簡化分發和執行Java程序包。盡管有和JSR-376幾乎一樣的名字,但兩者最初的目標有著細微差別;雖然它的任務是修復“可靠 的配置”問題,但是它並不試圖解決“強封裝”的問題。相對於JSR-376,它也嘗試增加一個版本模型到Java程序包中。這些目標和OSGi提供的功能 之間的相似性是完全足夠讓作者在最初考慮把OSGi作為一個解決方案,放棄的原因考慮為OSGi的版本控制太弱了。

不久之後創建的JSR-294的目標是實現“改進Java程序語言的模塊性支持”。同時針對Java 7,JSR-294新增了模塊概念(所謂的“超級包”)來修復強封裝的問題;這個概念匹配了當前的Java平台模塊系統項目。當Java 7的目標被放棄時,JSR-277和JSR-294從2012年開始被凍結,由JSR-376代替。

OSGi和模塊化Java的另一個關聯能在JSR-291中找到,“Java SE的動態組件支持”(本質上是OSGi服務平台發布的第四版)。JSR-291參考了JSR-277,作為最早的Java模塊系統,來主動區分兩者之間 的不同作用:JSR-277關注Java中使用的靜態模塊定義,而JSR-291關注運行時動態組件的加載和卸載。

最後,JSR-376也參考了OSGi,放棄它作為有效解決方案的主要原因是因為它的范圍遠遠大於Java框架模塊系統規范。

綜上所述,多數人難以區分新的模塊系統和OSGi是正常的。但是,模塊系統和OSGi相互補充,用以服務於不同的目標,OSGi作為一個構建於 Java之上的框架,在一個持續運行的應用中,創建了一個用以動態管理bundle的環境,而模塊系統作為Java本身的新能力能夠更緊密更簡單的控制靜 態模塊。

Java平台模塊系統和OSGi的區別

為了更好的理解這一點,InfoQ請教了Holly Cummins,《Enterprise OSGi in Action》的作者之一。不過以下內容並不會徹底說清楚Java平台模塊系統和OSGi之間的差異,只是為讀者提供一個基本的理解關於兩者目標的區別。

一方面,Java新的模塊系統將會提供更簡單的方式在編譯時檢查包和類的可見性,但是當我們詢問OSGi的bundle是否能用相同的方式使用時,Holly表示“答案是相當的復雜”。

OSGi通過bundle的清單文件來描述依賴,有兩種基本方式來創建清單文件:“代碼優先”和“清單文件優先”。代碼優先方式(使用bnd工 具,和maven bundle插件),並不會在編譯時檢查依賴列表,實際上它是在編譯時生成的。在通常方式的編譯過程中,工具會根據編譯時的依賴統計出運行時的依賴。另一 種方式是清單文件優先,通過Eclipse PDE工具來使用。在這種方式中,依賴被聲明在清單文件中,Eclipse IDE會使用這份清單文件統計出你的代碼能訪問的類,並高亮缺失的依賴。PDE命令行構建和一個叫做Tycho的Maven插件,都會在編譯時檢查依賴關 系。但是,請注意OSGi自己並不會檢查可見性,而是通過PDE自帶的工具;因為不是所有使用PDE的團隊都會使用其中的工具,有時候可能會在編譯時造成 缺少依賴。

新的模塊系統的另一個重要方面是能夠限定指定包對模塊的導出,這是很有用的當一批相互關聯的模塊需要互相訪問,但卻不能訪問其他內容時。正如Mark Reinhold在報告中指出的,這能夠用以下語法來實現:

module java.base {
...
exports sun.reflect to
java.corba,
java.logging,
java.sql,
java.sql.rowset,
jdk.scripting.nashorn;
}

OSGi最初並沒有這個能力,但增加之後能夠讓它比模塊系統的目標走的更遠。Holly解釋道,“所有的bundle都能夠注冊成一個解析攔截器, 用以過濾匹配,因此包只會暴露給指定的bundle。當導出聲明了確定的元數據的包給bundle時,你能夠使用相同的機制來預測,或者只是在每周二瘋狂 的導出包”。

查看英文原文Oracle Publishes Report on the State of Java’s Module System

Copyright © Linux教程網 All Rights Reserved