Java Platform Module System ( JPMS ) は、 Javaコードと関連リソースのコレクションの配布形式を規定しています。 [ 1 ]また、これらのコレクション、つまりモジュールを格納するリポジトリを規定し、それらを検出、ロード、および整合性チェックする方法を識別します。既存のJAR形式の欠点、特にクラスパスやクラスロードの問題などを引き起こす可能性のあるJAR Hellを修正することを目的として、名前空間などの機能が含まれています。
Javaモジュールシステムは当初、Javaコミュニティプロセスの下でJSR 277として開発され、Java 7でリリースされる予定だった。
JSR 277は後に保留となり、JDKをモジュール化するためにProject Jigsaw [ 2 ]が作成されました。このJSRはJSR 376(Java Platform Module System)に置き換えられました。
Project Jigsaw は当初Java 7 (2011 年) 向けに計画されていましたが、プラン B の一環としてJava 8 (2014 年) に延期され、 [ 3 ] 2017 年にJava 9リリースに再び延期されました。[ 4 ] Java モジュール システムを含む Java 9 は、2017 年 9 月 21 日にリリースされました。[ 5 ] [ 6 ]
Java 9 で実装された Java モジュール システムには、次のJEPとJSR (Java 仕様要求)が含まれています。[ 2 ]
さらに、モジュールシステムへの移行を容易にするために、JDK 9には他にもいくつかの機能が追加されています。
モジュールはパッケージをグループ化し、どのパッケージがパブリック API に属するかを厳密に制御するために使用されます。Jarファイルとは異なり、モジュールは依存するモジュールとエクスポートするパッケージを明示的に宣言します。[ 13 ]明示的な依存関係の宣言により、大規模なアプリケーションやソフトウェア コンポーネント間の依存関係について推論しやすくなり、コードの整合性が向上します。
モジュール宣言は、モジュールのソースファイル階層のルートにあるmodule-info.javaというファイルに配置されます。JDK は、コンパイル時と実行時の両方で、モジュール間の依存関係と相互作用を検証します。
例えば、次のモジュール宣言は、モジュールがorg.wikipedia.bar別のモジュールに依存していることを宣言しorg.wikipedia.baz、次のパッケージをエクスポートしorg.wikipedia.bar.alphaますorg.wikipedia.bar.beta。
module org.wikipedia.bar { requires org.wikipedia.baz; exports org.wikipedia.bar.alpha; exports org.wikipedia.bar.beta; }org.wikipedia.bar.alphaパッケージのパブリックメンバーはorg.wikipedia.bar.beta依存モジュールからアクセスできます。プライベートメンバーはリフレクションなどの手段を使ってもアクセスできません。Javaバージョン9 から 16 では、このような「不正アクセス」が事実上許可されるかどうかはコマンドライン設定に依存することに注意してください。 [ 14 ]
Java 9では、JDK自体がモジュール化されています。[ 15 ]例えば、Java標準ライブラリの大部分はモジュールによってエクスポートされていますjava.base。
Java 25以降では、モジュール自体をインポートすることができ、エクスポートされたすべてのパッケージが自動的にインポートされます。[ 16 ]これは を使用して行われますimport module。たとえば、は と同等です。importmodulejava.sql;
import java.sql.* ; import javax.sql.* ; // java.logging、java.transaction.xa、java.xml からの残りの間接エクスポート同様に、同様に、はに属する 54 個のパッケージすべてをインポートします。importmodulejava.base;java.base
パッケージorg.wikipedia.examples ;import module java.base ;/** * java.base モジュールをインポートすることで、ほとんどのクラスを手動でインポートする必要がなくなります。 * 以下のクラス (java.lang 以外) が使用されます。* - java.text.MessageFormat * - java.util.Date * - java.util.List * - java.util.concurrent.ThreadLocalRandom */ public class Example { public static void main ( String [] args ) { List < String > colours = List . of ( "Red" , " Orange " , "Yellow" , "Green" , "Blue" , "Indigo" , "Violet" ); IO . println ( MessageFormat . format ( "My favourite colour is {0} and today is {1,date,long}" , colours . get ( ThreadLocalRandom . current (). nextInt ( colours . size ())), new Date () )); } }モジュールでは以下のキーワードを使用します。
exports: モジュール宣言で使用され、他のモジュールで使用可能なパッケージを指定します。module: モジュールを宣言しますopen: パッケージ内のすべてのクラスが、他のモジュールからリフレクションを介してアクセス可能であることを示しますopens: 他のモジュールへのリフレクションのために特定のパッケージを開くために使用されますprovides: モジュールがサービスインターフェースの実装を提供すると宣言するために使用されますrequires: モジュール宣言で使用され、モジュールが別のモジュールに依存していることを指定します。to:opensディレクティブと共に使用され、どのモジュールがパッケージにリフレクションアクセスできるかを指定します。transitive: ディレクティブと共に使用されrequires、モジュールが別のモジュールを必要とするだけでなく、そのモジュールの依存関係を、それに依存するモジュールにも利用可能にすることを示す。uses: モジュール内で使用され、そのモジュールがサービスを使用すること(つまり、他のモジュールが提供するサービスを利用すること)を宣言するために使用されます。with:providesディレクティブと共に使用され、モジュールによって提供されるサービスの実装を指定します。名前空間のモジュールはJava Platform, Standard Editionjava.*に属し、名前空間のモジュールはJava Development Kitに属します。[ 17 ]jdk.*
このモジュールは公式のモジュールではありませんが、 Java 標準ライブラリのjdk.unsupported実装の詳細を表すため、JDK にバンドルされることがよくあります。[ 18 ]名前空間( CPU とハードウェアを操作したり、メモリを直接管理したりするために使用されるクラスを含む) [ 19 ]とパッケージが含まれています。sun.*sun.misc.Unsafecom.sun.*
module jdk . unsupported { exports sun . misc ; exports sun . reflect ; exports com . sun . nio . file ;sun.miscを開きます。sun.reflectを開きます。}Jakarta EEは、かつてJava標準ライブラリの一部でしたが、モジュール化されていません。ただし、ビルドシステムはJakarta EE用のモジュールを自動的に生成できます。
JavaFXは以前はコアJDKにバンドルされていましたが、Java 11でOpenJFXに分割されました。JavaFXは以下のモジュールに分割されています。[ 20 ]
Java モジュール システムでは、 OSGiプラットフォームが現在サポートしているすべての機能(たとえば、ライフサイクル モデルやサービス レジストリなど) をサポートすることは意図されていません。ただし、Java モジュール システムでは、コンパイル時のモジュール性やネイティブ ライブラリの組み込みサポートなど、OSGi ではサポートされていない機能をサポートします。[ 21 ] Java モジュール システムと OSGi がどのように相互運用できるかを検証した記事が 2016 年にいくつか公開されました。これらは InfoQ [ 22 ]および OSGi Alliance Blog [ 23 ]で見つけることができます。