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

クラスModuleLayer

java.lang.Object
java.lang.ModuleLayer

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

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

レイヤーを作成すると、構成内のResolvedModuleごとにModuleオブジェクトが作成されます。 readの解決済モジュールごとに、Module readsは対応するランタイムModuleです。これは、同じレイヤーまたはparentレイヤーにある場合があります。

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

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

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

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

適格なオープンは、適格なエクスポートと同様に処理されます。

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

特に指定しないかぎり、このクラスのメソッドに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
関連項目:
  • メソッドの詳細

    • 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")がセキュリティ・マネージャによって拒否された場合
      関連項目:
    • 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")がセキュリティ・マネージャによって拒否された場合
      関連項目:
    • 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 - 指定された構成のtheparent(s)が、順序を含む親レイヤーの構成と一致しない場合
      LayerInstantiationException - 上記のいずれかの理由により、すべてのモジュールを同じクラス・ローダーに定義できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
    • 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 - 指定された構成のtheparent(s)が、順序を含む親レイヤーの構成と一致しない場合
      LayerInstantiationException - 構成に"java.base"という名前のモジュールが含まれているか、"java"という名前のパッケージまたは"java."で始まる名前のパッケージがモジュールに含まれているため、レイヤーを作成できない場合
      SecurityException - RuntimePermission("createClassLoader")またはRuntimePermission("getClassLoader")がセキュリティ・マネージャによって拒否された場合
      関連項目:
    • defineModules

      public static ModuleLayer.Controller defineModules(Configuration cf, List<ModuleLayer> parentLayers, Function<String,ClassLoader> clf)
      指定された ConfigurationのモジュールをJava仮想マシンに定義して、新しいモジュール・レイヤーを作成します。 指定された関数は、構成内の各モジュールを名前でクラス・ローダーにマップします。 レイヤーを作成すると、ロード可能なクラスがJava仮想マシンに通知され、各クラスがメンバーであるモジュールがJava仮想マシンで認識されます。

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

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

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

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

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

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

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

      APIのノート:
      このメソッドを使用してレイヤーを作成することが不可分操作であるかどうかについては、実装に固有です。 その結果、Java仮想マシンに定義されている一部のモジュール(すべてではない)でこのメソッドが失敗する可能性があります。
      パラメータ:
      cf - レイヤーの構成
      parentLayers - 検索順序の親レイヤーのリスト
      clf - モジュール名をクラス・ローダーにマップする関数
      戻り値:
      新しく作成されたレイヤーを制御するコントローラ
      例外:
      IllegalArgumentException - 指定された構成のtheparent(s)が、順序を含む親レイヤーの構成と一致しない場合
      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のノート:
      `null`はブートストラップ・クラス・ローダーを表すために使用する必要があるため、このメソッドはOptional<ClassLoader>を返しません。
      パラメータ:
      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を返します。
      戻り値:
      ブート層