web-dev-qa-db-ja.com

Jigsaw / JPMSをプロジェクトする理由

Javaのパッケージ管理システムは、常にシンプルで効果的であるように思えました。 JDK自体によって頻繁に使用されます。これを使用して、名前空間とモジュールの概念を模倣しています。

Project Jigsaw(別名 Java Platform Module System )記入しようとしていますか?

公式サイトから:

このプロジェクトの目標は、Java SEプラットフォームの標準モジュールシステムを設計および実装し、そのシステムをプラットフォーム自体およびJDKに適用することです。

78
John

JigsawとOSGiは、同じ問題を解決しようとしています。つまり、より粗いモジュールを相互作用させながら内部をシールドする方法です。

Jigsawの場合、粗いモジュールにはJavaクラス、パッケージ、およびそれらの依存関係が含まれます。

次に例を示します。SpringとHibernate。どちらもサードパーティのJAR CGLIBに依存していますが、異なるJARの互換性のないバージョンを使用しています。標準のJDKに依存している場合、何ができますか? Springが望んでいるバージョンを含めると、Hibernateが壊れ、その逆も成り立ちます。

しかし、Jigsawのような上位レベルのモデルがある場合、異なるモジュールで異なるバージョンのJARを簡単に管理できます。それらを上位レベルのパッケージと考えてください。

GitHubソースからのスプリング をビルドすると、それも表示されます。彼らはフレームワークをやり直したので、コア、永続性などのいくつかのモジュールで構成されています。アプリケーションが必要とするモジュール依存関係の最小セットを選択して、残りを無視できます。以前は、すべての.classファイルを含む単一のSpring JARでした。

更新:5年後-ジグソーにはまだ解決すべき issues があるかもしれません。

100
duffymo

知る計画は、JREをよりモジュール化することです。つまりオプションの小さなjarがあり、必要な機能のみをダウンロード/アップグレードできます。

肥大化を抑え、おそらくほとんどの人が使用しないレガシーモジュールを削除するオプションを提供します。

43
Peter Lawrey

Mark ReinholdDevoxx Belgiumでの基調講演 に基づいて、Project Jigsawは2つの主要な問題点に対処します。

  1. クラスパス
  2. 大規模なモノリシックJDK

クラスパスの何が問題になっていますか?


JAR Hell については誰もが知っています。この用語は、classloadingプロセスが機能しなくなるさまざまな方法をすべて説明しています。クラスパスの最も知られている制限は次のとおりです。

  • 競合があるかどうかを判断するのは困難です。 Mavenのようなビルドツールは、アーティファクト名に基づいてかなり良い仕事をすることができますが、アーティファクト自体が異なる名前で同じコンテンツを持っている場合、競合が発生する可能性があります。
  • Jarファイルの基本的な問題は、それらがコンポーネントではないことです。それらは、直線的に検索されるファイルコンテナの集まりです。クラスパスは、クラスのコンポーネント、クラスのパッケージ、または使用目的に関係なく、クラスを検索する方法です。

大規模なモノリシックJDK


JDKの大きなモノリシックの性質は、いくつかの問題を引き起こします。

  • 小型デバイスには適合しません。小さいIoTタイプのデバイスには、SEクラスを実行できるプロセッサがありますが、VMですが、特にアプリケーションがそのごく一部しか使用しない場合、すべてのJDKを保持するためのメモリがありません。
  • クラウドでも問題です。クラウドは、ハードウェアの使用を最適化することです。JDK全体を含む数千のイメージがあり、アプリケーションがその一部しか使用しない場合、それは無駄になります。

モジュール:一般的なソリューション


上記の問題に対処するために、モジュールを基本的な新しい種類のJavaプログラムコンポーネントとして扱います。モジュールは、名前と自己記述のコードとデータのコレクションです。そのコードはセットとして編成されますJavaクラスとインターフェイス。タイプには、リソースと他の種類の静的情報が含まれます。

コードが他のモジュールの型をどのように参照するかを制御するために、モジュールは、コンパイルおよび実行するために必要な他のモジュールを宣言します。他のモジュール内のコードがパッケージ内の型を参照する方法を制御するために、モジュールはそれらのパッケージのどれをエクスポートするかを宣言します。

モジュールシステムは必要なモジュールを見つけ、クラスパスメカニズムとは異なり、モジュール内のコードが依存するモジュール内の型のみを参照できるようにします。 Java言語およびJava仮想マシンのアクセス制御メカニズムは、定義モジュールによってエクスポートされないパッケージ内のタイプにコードがアクセスするのを防ぎます。

モジュール性により、信頼性が向上するだけでなく、パフォーマンスが向上する可能性があります。モジュール内のコードがパッケージ内の型を参照する場合、そのパッケージは、そのモジュール内、またはそのモジュールによって読み取られたモジュールの1つで定義されることが保証されます。したがって、特定のタイプの定義を検索する場合、複数のモジュールで検索したり、さらに悪いことにクラスパス全体で検索したりする必要はありません。

フォローするJEP


ジグソーパズルは非常に大きなプロジェクトであり、かなりの数年間続いています。プロジェクトに関する詳細情報を入手するには絶好の場所である印象的な量のJEPがあります。これらのJEPの一部は次のとおりです。

  • JEP 200:The Modular JDKJavaプラットフォームモジュールシステム(JPMS)を使用してJDKをモジュール化する=
  • JEP 201:モジュラーソースコードJDKソースコードをモジュールに再編成し、ビルドシステムを拡張してモジュールをコンパイルし、ビルド時にモジュール境界を強制する
  • JEP 261:モジュールシステムJava JSR 376で指定されたプラットフォームモジュールシステム、および関連するJDK固有の変更と機能強化) =
  • JEP 220:モジュラーランタイムイメージJDKおよびJREランタイムイメージを再構築して、モジュールに対応し、パフォーマンス、セキュリティ、および保守性を改善します
  • JEP 260:ほとんどの内部APIをカプセル化JDKの内部APIのほとんどをデフォルトでアクセス不可にしますが、一部またはすべてのサポートされる代替が存在するまで、広く使用されている重要な内部APIをいくつかアクセス可能にします機能の
  • JEP 282:jlink:Java Linkerモジュールのセットとその依存関係をカスタムランタイムにアセンブルおよび最適化できるツールを作成する JEP 22で定義されている画像

閉会の辞


モジュールシステムの状態 レポートの初期版では、Mark Reinholdはモジュールシステムの具体的な目標を次のように説明しています。

  • 信頼性の高い構成、脆弱でエラーが発生しやすいクラスパスメカニズムを、プログラムコンポーネントが相互に明示的な依存関係を宣言する手段に置き換える
  • 強力なカプセル化。コンポーネントが他のコンポーネントにアクセスできるパブリック型とアクセスできないパブリック型を宣言できるようにします。

これらの機能は、アプリケーション開発者、ライブラリ開発者、およびJava SEプラットフォーム自体の実装者にとっても、間接的にもメリットがあります。スケーラブルなプラットフォーム、プラットフォームの整合性、パフォーマンスの向上を可能にするためです。

42
Ali Dehghani

引数のために、Java 8(およびそれ以前)already hasa form of a modules(jars)and module system) (クラスパス)しかし、これらにはよく知られた問題があります。

問題を調べることで、ジグソーパズルの動機を説明できます。 (以下では、確実にソリューションを提供するOSGiやJBossモジュールなどを使用していないことを前提としています。)

問題1:パブリックはtoopublic

次のクラスを検討してください(両方がパブリックであると仮定します):

com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl

Foo.comでは、チームはUserDaoを使用し、UserDaoImplを直接使用しないことを決定する場合があります。ただし、クラスパスでそれを強制する方法はありません。

Jigsawでは、モジュールにはmodule-info.Javaファイルが含まれており、他のモジュールに公開されているものを明示的に指定できます。つまり、大衆にはニュアンスがあります。例えば:

// com.acme.foo.db.api.UserDao is accessible, but
// com.acme.foo.db.impl.UserDaoImpl is not 
module com.acme.foo.db {
    exports com.acme.foo.db.api;
}

問題2:反射が妨げられない

#1のクラスを考えると、誰かがJava 8:

Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();

つまり、リフレクションは強力で不可欠ですが、チェックされていない場合、望ましくない方法でモジュールの内部に到達するために使用できます。 Mark Reinholdには、むしろ alarming example があります。 (SO投稿は ここ です。)

ジグソーパズルでは、強力なカプセル化により、リフレクションを含むクラスへのアクセスを拒否できます。 (これは、JDK 9の改訂された技術仕様を保留しているコマンドライン設定に依存する可能性があります。)JigsawはJDK自体に使用されるため、OracleはJavaチームがプラットフォーム内部をより迅速に革新します。

問題3:クラスパスはアーキテクチャ上の関係を消去します

通常、チームには、jarファイル間の関係についてのメンタルモデルがあります。たとえば、foo-app.jarfoo-services.jarを使用するfoo-db.jarを使用できます。 foo-app.jarのクラスは「サービス層」をバイパスしてはならず、foo-db.jarを直接使用する必要があると断言できます。ただし、クラスパスを介して強制する方法はありません。 Mark Reinholdが this here に言及している。

比較すると、Jigsawはモジュールに対して明示的で信頼性の高いアクセシビリティモデルを提供します。

問題4:モノリシックランタイム

Javaランタイムはモノリシックrt.jarにあります。私のマシンでは、2万クラスの60+ MBです!マイクロサービス、IoTデバイスなどの時代では、 Corba、Swing、XML、およびその他のライブラリが使用されていない場合、それらをディスク上に置くことは望ましくありません。

Jigsawは、JDK自体を多くのモジュールに分割します。例えば Java.sql には、使い慣れたSQLクラスが含まれています。これにはいくつかの利点がありますが、新しいものはjlinkツールです。アプリが完全にモジュール化されていると仮定すると、jlink配布可能な実行時イメージ を生成し、指定されたモジュール(およびその依存関係)のみを含むようにトリミングします。今後は、Oracle 将来を想定 JDKモジュールがネイティブコードに事前にコンパイルされます。 jlinkはオプションであり、AOTコンパイルは実験的ですが、これらはOracleの今後の方向性を示す主要な指標です。

問題5:バージョン管理

クラスパスでは、同じjarの複数のバージョンを使用できないことがよく知られています。 bar-lib-1.1.jarおよびbar-lib-2.2.jar

ジグソーパズルはこの問題に対処していません。マーク・ラインホールドは ここに根拠 と述べています。要点は、Maven、Gradle、およびその他のツールが依存関係管理のための大規模なエコシステムであり、別のソリューションは有益というよりも有害であることです。

他のソリューション(OSGiなど)が実際にこの問題に対処していることに注意する必要があります(#4は別として)。

下線

これは、特定の問題に動機付けられたジグソーパズルの重要なポイントです。

Jigsaw、OSGi、JBoss Modulesなどの間の論争を説明することは、別のStack Exchangeサイトに属する別個の議論であることに注意してください。ソリューションには、ここで説明したものよりも多くの違いがあります。さらに、JSR 376の パブリックレビュー再検討投票 を承認するための十分なコンセンサスがありました。

13
Michael Easter

この記事では、OSGiとJPMS/Jigsawの両方が解決しようとする問題について詳しく説明します。

"Java 9、OSGiとモジュール方式の未来" [22 SEP 2016]

また、OSGiとJPMS/Jigsawの両方のアプローチについても徹底的に説明します。現時点では、著者は、成熟した(16歳の)OSGiと比較して、JPMS/Jigsawの実用的なProをほとんどリストしていないようです。

3
uvsmtid