モジュール java.base
パッケージ java.lang

クラスModuleLayer

java.lang.Object
java.lang.ModuleLayer

public final class ModuleLayer
extends Object
Java仮想マシン内のモジュールのレイヤー。

レイヤーは、Configuration内のモジュールのグラフから作成され、各モジュールをClassLoaderにマップする関数です。 レイヤーを作成すると、Java仮想マシンが各クラスがメンバーであるモジュールを認識できるように、モジュールからロードできるクラスについてJava仮想マシンに通知します。

レイヤーを作成すると、構成内の各ResolvedModuleModuleオブジェクトが作成されます。 readである解決されたモジュールごとに、Module readsは、対応する実行時Module(同じレイヤーまたはparentレイヤー内にある可能性があります)。

defineModulesWithOneLoaderおよびdefineModulesWithManyLoadersメソッドは、すべてのモジュールが単一のクラス・ローダーにマップされるモジュール・レイヤーを作成する便利な方法を提供します。または、各モジュールが独自のクラス・ローダーにマップされる場所です。 defineModulesメソッドは、メソッドに指定された関数を使用してモジュールがカスタム・クラス・ローダーにマップされる、より高度な場合に使用します。 これらのメソッドのそれぞれにはインスタンスと静的バリアントがあります。 インスタンス・メソッドは、バーを親レイヤーとするレイヤーを作成します。 静的メソッドは、複数の親レイヤーが存在する可能性がある、またはレイヤー内のモジュールを制御するためにControllerが必要な、より高度なケース用です

Java仮想マシンには、Java仮想マシンの起動時に作成される少なくとも1つの空でないレイヤー、bootレイヤーがあります。 ブート・レイヤーにはモジュールjava.baseが含まれ、"java.base"という名前のモジュールを持つJava仮想マシンの唯一のレイヤーです。 ブート・レイヤーのモジュールは、ブートストラップ・クラス・ローダーとJava仮想マシンのbuilt-inである他のクラス・ローダーにマップされます。 ブート・レイヤーは、追加のレイヤーを作成するときによくparentになります。

レイヤー内の各Moduleは、そのModuleDescriptorで記述されたパッケージをexportsopensが作成するように作成されます。 修飾されたエクスポート (パッケージがすべてのモジュールではなくターゲット・モジュールのセットにエクスポートされる)は、次のようにレイヤーを作成するときに具象化されます:

  • モジュールXがパッケージをYにエクスポートし、ランタイムModule XModule Yを読み取る場合、パッケージはModule Y (これはXと同じレイヤーまたは親レイヤーにあります)にエクスポートされます。
  • モジュールXがパッケージをYにエクスポートし、ランタイムModule XYを読み取らない場合、Yは、findModuleを呼び出してレイヤーまたはその親レイヤー内のモジュールを検索するかのように配置されます。 Yが見つかった場合、パッケージはYのインスタンスにエクスポートされます。 Yが見つからない場合、修飾されたエクスポートは無視されます。

修飾されたオープンは、修飾されたエクスポートと同じ方法で処理されます。

Configurationを作成するときと同様に、automaticモジュールは、レイヤーを作成するときに特別な処理を受け取ります。 Java仮想マシン内で、Java仮想マシン内の無名の Moduleをすべて読み取るModuleとして、自動モジュールが作成されます。

特に指定しない限り、null引数をこのクラスのメソッドに渡すと、NullPointerExceptionがスローされます。

使用例:

この例では、ブート層の構成を親として、"myapp"という名前のモジュールを解決して構成を作成します。 次に、この構成でモジュールを使用して新しいレイヤーを作成します。 すべてのモジュールは同じクラス・ローダーに定義されています。


     ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);

     ModuleLayer parent = ModuleLayer.boot();

     Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));

     ClassLoader scl = ClassLoader.getSystemClassLoader();

     ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);

     Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
 
導入されたバージョン:
9
関連項目:
Module.getLayer()
  • メソッドの詳細

    • defineModulesWithOneLoader

      public ModuleLayer defineModulesWithOneLoader​(Configuration cf, ClassLoader parentLoader)
      指定されたConfiguration内のモジュールをJava仮想マシンに定義することによって、この層を親として持つ新しいモジュール層を作成します。 このメソッドは、1つのクラス・ローダーを作成し、そのクラス・ローダーへのすべてのモジュールを定義します。 各クラス・ローダーのparentは、指定された親クラス・ローダーです。 このメソッドは、このレイヤーを親として呼び出すときに、静的なdefineModulesWithOneLoaderメソッドで指定されたとおりに機能します。 つまり、このレイヤーがthisLayerの場合、このメソッドは次の呼び出しと同じです:
       
           ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
       
      パラメータ:
      cf - レイヤーの構成
      parentLoader - このメソッドで作成されたクラス・ローダーの親クラス・ローダー。ブートストラップ・クラス・ローダー用のnull
      戻り値:
      新しく作成されたレイヤー
      例外:
      IllegalArgumentException - 指定された構成に複数の親がある場合、または構成の親がこの層の構成でない場合
      LayerInstantiationException - 静的なdefineModulesWithOneLoaderメソッドで指定された理由のいずれかでレイヤーを作成できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
      findLoader(java.lang.String)
    • defineModulesWithManyLoaders

      public ModuleLayer defineModulesWithManyLoaders​(Configuration cf, ClassLoader parentLoader)
      指定されたConfiguration内のモジュールをJava仮想マシンに定義することによって、この層を親として持つ新しいモジュール層を作成します。 各モジュールは、このメソッドで作成された独自のClassLoaderに定義されています。 各クラス・ローダーのparentは、指定された親クラス・ローダーです。 このメソッドは、このレイヤーを親として呼び出すときに、静的なdefineModulesWithManyLoadersメソッドで指定されたとおりに機能します。 つまり、このレイヤーがthisLayerの場合、このメソッドは次の呼び出しと同じです:
       
           ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
       
      パラメータ:
      cf - レイヤーの構成
      parentLoader - このメソッドで作成された各クラス・ローダーの親クラス・ローダー;ブートストラップ・クラス・ローダー用はnullかもしれません
      戻り値:
      新しく作成されたレイヤー
      例外:
      IllegalArgumentException - 指定された構成に複数の親がある場合、または構成の親がこの層の構成でない場合
      LayerInstantiationException - 静的なdefineModulesWithManyLoadersメソッドで指定された理由のいずれかでレイヤーを作成できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
      findLoader(java.lang.String)
    • defineModules

      public ModuleLayer defineModules​(Configuration cf, Function<String,​ClassLoader> clf)
      指定されたConfiguration内のモジュールをJava仮想マシンに定義することによって、この層を親として持つ新しいモジュール層を作成します。 各モジュールは、指定された関数を使用してクラス・ローダーに名前でマップされます。 このメソッドは、このレイヤーを親として呼び出すときに、静的なdefineModulesメソッドで指定されたとおりに機能します。 つまり、このレイヤーがthisLayerの場合、このメソッドは次の呼び出しと同じです:
       
           ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
       
      パラメータ:
      cf - レイヤーの構成
      clf - モジュール名をクラス・ローダーにマップする関数
      戻り値:
      新しく作成されたレイヤー
      例外:
      IllegalArgumentException - 指定された構成に複数の親がある場合、または構成の親がこの層の構成でない場合
      LayerInstantiationException - 静的なdefineModulesメソッドで指定された理由のいずれかでレイヤーを作成できない場合
      SecurityException - RuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
    • defineModulesWithOneLoader

      public static ModuleLayer.Controller defineModulesWithOneLoader​(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
      指定された Configuration内のモジュールをJava仮想マシンに定義することによって、新しいモジュール層を作成します。 このメソッドは、1つのクラス・ローダーを作成し、そのクラス・ローダーへのすべてのモジュールを定義します。

      このメソッドで作成されたクラス・ローダーは、モジュールからクラスをロードするときに「直接委任」を実装します。 クラスをロードするためにloadClassメソッドが呼び出された場合、クラスのパッケージ名を使用してクラスにモジュールをマップします。 これは、このレイヤーのモジュールであり、したがって同じクラス・ローダーに定義されている可能性があります。 これは、このレイヤーの1つまたは複数のモジュールにエクスポートされる、親レイヤーのモジュール内のパッケージである場合があります。 クラス・ローダーは、モジュールのクラス・ローダーに委譲し、そのクラス・ローダーによって見つからなければ ClassNotFoundExceptionを投げます。 モジュールにマップされていないクラスをロードするためにloadClassが呼び出されると、親クラス・ローダーに委譲されます。

      このメソッドで作成されたクラス・ローダーは、親クラス・ローダーを検索する前に、レイヤー内のすべてのモジュールでリソース(getResourcegetResources、およびその他のリソース・メソッド)を探します。

      同じクラス・ローダーに定義されたすべてのモジュールを含むレイヤーを作成しようとすると、次のような理由で失敗する可能性があります:

      • 重複するパッケージ: 構成内の2つ以上のモジュールが同じパッケージを持っています。

      • 委任を分割: 結果として生じるクラス・ローダーは、特定のパッケージにクラスをロードするために、複数のクラス・ローダーに委譲する必要があります。

      さらに、構成に"java.base"という名前のモジュールが含まれている場合、またはモジュールに"java"という名前のパッケージまたは"java."で始まる名前のパッケージが含まれている場合は、レイヤーを作成できません。

      セキュリティ・マネージャが存在する場合、このメソッドによって作成されたクラス・ローダーは、このメソッドの呼び出しコンテキストによって制限される特権を持つクラスおよびリソースをロードします。

      パラメータ:
      cf - レイヤーの構成
      parentLayers - 検索順序の親レイヤーのリスト
      parentLoader - このメソッドで作成されたクラス・ローダーの親クラス・ローダー。ブートストラップ・クラス・ローダー用のnull
      戻り値:
      新しく作成されたレイヤーを制御するコントローラ
      例外:
      IllegalArgumentException - 指定された構成の親が、順序を含む親の層の構成と一致しない場合
      LayerInstantiationException - 上記のいずれかの理由により、すべてのモジュールを同じクラス・ローダーに定義できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
      findLoader(java.lang.String)
    • defineModulesWithManyLoaders

      public static ModuleLayer.Controller defineModulesWithManyLoaders​(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
      指定された Configuration内のモジュールをJava仮想マシンに定義することによって、新しいモジュール層を作成します。 各モジュールは、このメソッドで作成された独自のClassLoaderに定義されています。 各クラス・ローダーのparentは、指定された親クラス・ローダーです。

      このメソッドで作成されたクラス・ローダーは、モジュールからクラスをロードするときに「直接委任」を実装します。 クラスをロードするためにloadClassメソッドが呼び出された場合、クラスのパッケージ名を使用してクラスにモジュールをマップします。 パッケージは、クラス・ローダーに定義されたモジュール内に存在することがあります。 パッケージは、このレイヤー内の別のモジュールによってクラス・ローダーに定義されたモジュールにエクスポートできます。 これは、親レイヤーのモジュールによってエクスポートされたパッケージ内に存在する可能性があります。 クラス・ローダーは、モジュールのクラス・ローダーに委譲し、そのクラス・ローダーによって見つからなければClassNotFoundExceptionを投げます。 モジュールにマップされないクラスをロードするためにloadClassが呼び出されると、親クラス・ローダーに委譲されます。

      このメソッドで作成されたクラス・ローダーは、親クラス・ローダーを検索する前にクラス・ローダーに定義されたモジュールのresources (getResourcegetResources、およびその他のリソース・メソッド)を探します。

      セキュリティ・マネージャが存在する場合、このメソッドで作成されたクラス・ローダーは、このメソッドの呼び出しコンテキストによって制限される特権を持つクラスとリソースをロードします。

      パラメータ:
      cf - レイヤーの構成
      parentLayers - 検索順序の親レイヤーのリスト
      parentLoader - このメソッドで作成された各クラス・ローダーの親クラス・ローダー;ブートストラップ・クラス・ローダー用はnullかもしれません
      戻り値:
      新しく作成されたレイヤーを制御するコントローラ
      例外:
      IllegalArgumentException - 指定された構成の親が、順序を含む親の層の構成と一致しない場合
      LayerInstantiationException - 構成に"java.base"という名前のモジュールが含まれているか、"java"という名前のパッケージまたは"java."で始まる名前のパッケージがモジュールに含まれているため、レイヤーを作成できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
      findLoader(java.lang.String)
    • defineModules

      public static ModuleLayer.Controller defineModules​(Configuration cf, List<ModuleLayer> parentLayers, Function<String,​ClassLoader> clf)
      指定された Configuration内のモジュールをJava仮想マシンに定義することによって、新しいモジュール層を作成します。 指定された関数は、コンフィギュレーション内の各モジュールを名前でクラス・ローダーにマップします。 レイヤーを作成することにより、Java仮想マシンが各クラスがメンバーであるモジュールを知るように、ロードできるクラスについてJava仮想マシンに通知します。

      クラス・ローダーによって実装されるクラス・ローダーの委譲は、モジュールの可読性を尊重する必要があります。 クラス・ローダーは、クラス・ロード中にデッドロックを避けるためにparallel-capableでなければなりません。 さらに、このメソッドを使用して新しいレイヤーを作成するエンティティは、クラスまたはリソースをロードしようとする前に、クラス・ローダーをこれらのモジュールからロードする準備を整える必要があります。

      レイヤーの作成に失敗する理由は次のとおりです:

      • 同じパッケージを持つ2つ以上のモジュールが同じクラス・ローダーにマップされます。

      • モジュールは既に定義されている同じ名前のモジュールを持つクラス・ローダーにマップされます。

      • モジュールは、モジュール内のいずれかのパッケージ内の型をすでに定義しているクラス・ローダーにマップされます。

      さらに、構成に"java.base"という名前のモジュールが含まれている場合、"java"という名前のパッケージを含む構成または"java."で始まるパッケージ名を含む構成、またはモジュール名をクラス・ローダーにマップする関数がnullを戻す場合は、レイヤーを作成できません。「プラットフォーム・クラス・ローダー」

      モジュール名をクラス・ローダーにマップする関数がエラーまたは実行時例外をスローすると、このメソッドの呼び出し側に伝播されます。

      APIのノート:
      このメソッドを使用してレイヤーを作成するかどうかは、アトミックな操作かどうかという点で実装固有です。 結果的に、このメソッドは、Java仮想マシンに定義されているモジュール(すべてではない)で失敗する可能性があります。
      パラメータ:
      cf - レイヤーの構成
      parentLayers - 検索順序の親レイヤーのリスト
      clf - モジュール名をクラス・ローダーにマップする関数
      戻り値:
      新しく作成されたレイヤーを制御するコントローラ
      例外:
      IllegalArgumentException - 指定された構成の親が、順序を含む親の層の構成と一致しない場合
      LayerInstantiationException - 上記のいずれかの理由でレイヤーの作成に失敗した場合
      SecurityException - RuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
    • configuration

      public Configuration configuration()
      このレイヤーの構成を返します。
      戻り値:
      このレイヤーの構成
    • parents

      public List<ModuleLayer> parents()
      親がなく、空のリストが返される「空の層」以外の場合は、このレイヤーの親のリストを返します。
      戻り値:
      この層の親のリスト
    • modules

      public Set<Module> modules()
      このレイヤー内のモジュールのセットを返します。
      戻り値:
      おそらく空の、このレイヤー内のモジュールの変更不可能なセット
    • findModule

      public Optional<Module> findModule​(String name)
      このレイヤー内に指定された名前のモジュールを返します。このレイヤー内にない場合は、parentレイヤーを返します。 親レイヤーでモジュールを見つけることは、モジュールが見つかるまで、またはすべての親が検索されるまで、各親で、検索順にfindModuleを呼び出すのと同じです。 「層の木」では、これは深さ優先探索と同じです。
      パラメータ:
      name - 検索するモジュールの名前
      戻り値:
      指定された名前のモジュールまたは空のOptionalこの層にこの名前のモジュールがない場合、または親の層
    • findLoader

      public ClassLoader findLoader​(String name)
      与えられた名前のモジュールのClassLoaderを返します。 指定された名前のモジュールがこの層にない場合、parent層はfindModuleで指定された方法で検索されます。

      セキュリティ・マネージャが存在する場合、checkPermissionメソッドがRuntimePermission("getClassLoader")アクセス許可で呼び出され、呼び出し元がクラス・ローダーへのアクセスを許可されているかどうかがチェックされます。

      APIのノート:
      このメソッドはOptional<ClassLoader>を返しません。なぜなら、`null`をブートストラップ・クラス・ローダーを表すために使用しなければならないからです。
      パラメータ:
      name - 検索するモジュールの名前
      戻り値:
      モジュールが定義されているClassLoader。
      例外:
      IllegalArgumentException - 指定された名前のモジュールがこのレイヤーまたはこのレイヤーのいずれかの親に定義されていない場合
      SecurityException - セキュリティ・マネージャによって拒否された場合
    • toString

      public String toString()
      このモジュール・レイヤーを説明する文字列を返します。
      オーバーライド:
      toString 、クラス:  Object
      戻り値:
      このモジュール・レイヤーを記述する空の文字列
    • empty

      public static ModuleLayer empty()
      emptyレイヤーを返します。 空のレイヤーにはモジュールがありません。 両親はいません。
      戻り値:
      空の層
    • boot

      public static ModuleLayer boot()
      ブート・レイヤーを返します。 ブート層には少なくとも1つのモジュールjava.baseが含まれています。 その親はempty層です。
      APIのノート:
      このメソッドは、起動時およびブート・レイヤーが完全に初期化される前にnullを返します。
      戻り値:
      ブート層