Javaのパッケージ管理システムは、常にシンプルで効果的であるように思えました。 JDK自体によって頻繁に使用されます。これを使用して、名前空間とモジュールの概念を模倣しています。
Project Jigsaw(別名 Java Platform Module System )記入しようとしていますか?
公式サイトから:
このプロジェクトの目標は、Java SEプラットフォームの標準モジュールシステムを設計および実装し、そのシステムをプラットフォーム自体およびJDKに適用することです。
JigsawとOSGiは、同じ問題を解決しようとしています。つまり、より粗いモジュールを相互作用させながら内部をシールドする方法です。
Jigsawの場合、粗いモジュールにはJavaクラス、パッケージ、およびそれらの依存関係が含まれます。
次に例を示します。SpringとHibernate。どちらもサードパーティのJAR CGLIBに依存していますが、異なるJARの互換性のないバージョンを使用しています。標準のJDKに依存している場合、何ができますか? Springが望んでいるバージョンを含めると、Hibernateが壊れ、その逆も成り立ちます。
しかし、Jigsawのような上位レベルのモデルがある場合、異なるモジュールで異なるバージョンのJARを簡単に管理できます。それらを上位レベルのパッケージと考えてください。
GitHubソースからのスプリング をビルドすると、それも表示されます。彼らはフレームワークをやり直したので、コア、永続性などのいくつかのモジュールで構成されています。アプリケーションが必要とするモジュール依存関係の最小セットを選択して、残りを無視できます。以前は、すべての.classファイルを含む単一のSpring JARでした。
更新:5年後-ジグソーにはまだ解決すべき issues があるかもしれません。
知る計画は、JREをよりモジュール化することです。つまりオプションの小さなjarがあり、必要な機能のみをダウンロード/アップグレードできます。
肥大化を抑え、おそらくほとんどの人が使用しないレガシーモジュールを削除するオプションを提供します。
Mark Reinhold の Devoxx Belgiumでの基調講演 に基づいて、Project Jigsawは2つの主要な問題点に対処します。
JAR Hell については誰もが知っています。この用語は、classloadingプロセスが機能しなくなるさまざまな方法をすべて説明しています。クラスパスの最も知られている制限は次のとおりです。
JDKの大きなモノリシックの性質は、いくつかの問題を引き起こします。
上記の問題に対処するために、モジュールを基本的な新しい種類のJavaプログラムコンポーネントとして扱います。モジュールは、名前と自己記述のコードとデータのコレクションです。そのコードはセットとして編成されますJavaクラスとインターフェイス。タイプには、リソースと他の種類の静的情報が含まれます。
コードが他のモジュールの型をどのように参照するかを制御するために、モジュールは、コンパイルおよび実行するために必要な他のモジュールを宣言します。他のモジュール内のコードがパッケージ内の型を参照する方法を制御するために、モジュールはそれらのパッケージのどれをエクスポートするかを宣言します。
モジュールシステムは必要なモジュールを見つけ、クラスパスメカニズムとは異なり、モジュール内のコードが依存するモジュール内の型のみを参照できるようにします。 Java言語およびJava仮想マシンのアクセス制御メカニズムは、定義モジュールによってエクスポートされないパッケージ内のタイプにコードがアクセスするのを防ぎます。
モジュール性により、信頼性が向上するだけでなく、パフォーマンスが向上する可能性があります。モジュール内のコードがパッケージ内の型を参照する場合、そのパッケージは、そのモジュール内、またはそのモジュールによって読み取られたモジュールの1つで定義されることが保証されます。したがって、特定のタイプの定義を検索する場合、複数のモジュールで検索したり、さらに悪いことにクラスパス全体で検索したりする必要はありません。
ジグソーパズルは非常に大きなプロジェクトであり、かなりの数年間続いています。プロジェクトに関する詳細情報を入手するには絶好の場所である印象的な量のJEPがあります。これらのJEPの一部は次のとおりです。
モジュールシステムの状態 レポートの初期版では、Mark Reinholdはモジュールシステムの具体的な目標を次のように説明しています。
これらの機能は、アプリケーション開発者、ライブラリ開発者、およびJava SEプラットフォーム自体の実装者にとっても、間接的にもメリットがあります。スケーラブルなプラットフォーム、プラットフォームの整合性、パフォーマンスの向上を可能にするためです。
引数のために、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.jar
はfoo-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の パブリックレビュー再検討投票 を承認するための十分なコンセンサスがありました。
この記事では、OSGiとJPMS/Jigsawの両方が解決しようとする問題について詳しく説明します。
"Java 9、OSGiとモジュール方式の未来" [22 SEP 2016]
また、OSGiとJPMS/Jigsawの両方のアプローチについても徹底的に説明します。現時点では、著者は、成熟した(16歳の)OSGiと比較して、JPMS/Jigsawの実用的なProをほとんどリストしていないようです。