ネイティブ・イメージでのリソースへのアクセス

デフォルトでは、native-imageビルダーは、クラスパスにあるどのリソースもネイティブ実行可能ファイルに統合しません。Class.getResource()Class.getResourceAsStream()などのコール(または対応するClassLoaderメソッド)で特定のリソース(nullではなく)を返すには、実行時にアクセス可能なリソースを指定する必要があります。これは、次の内容で構成ファイルを使用して実現できます:

{
  "resources": {
    "includes": [
      {"pattern": "<Java regexp that matches resource(s) to be included in the executable>"},
      {"pattern": "<another regexp>"},
      ...
    ],
    "excludes": [
      {"pattern": "<Java regexp that matches resource(s) to be excluded from the executable>"},
      {"pattern": "<another regexp>"},
      ...
    ]
  }
}

オプション-H:ResourceConfigurationFiles=/path/to/resource-config.jsonを使用して、native-imageツールへの構成ファイルのパスを指定します。または、次のように、native-imageツールへの個々のリソース・パスを直接指定できます:

native-image -H:IncludeResources="<Java regexp that matches resources to be included in the executable>" -H:ExcludeResources="<Java regexp that matches resources to be excluded from the executable>" ...

-H:IncludeResourcesおよび-H:ExcludeResourcesオプションを複数回渡して、それぞれリソースを含めるか除外する複数の正規表現を定義できます。

ネイティブ実行可能ファイルに含まれるリソースを確認するには、オプション-H:Log=registerResource:<log level>を使用します。<log level>引数は、1から5の範囲(詳細が最も低いレベルから最も高いレベル)である必要があります。3log levelでは、含まれるリソースの簡単な詳細を説明します。

使用例

次のプロジェクト構造を考えます:

my-app-root
└── src
    ├── main
    │   └── com.my.app
    │       ├── Resource0.txt
    │       └── Resource1.txt
    └── resources
        ├── Resource2.txt
        └── Resource3.txt

この場合、次のようになります:

ネイティブ実行可能ファイルにリソースを含める方法について説明しているこのガイドを確認してください。

ロケール

実行可能ファイルに含めるロケールと、デフォルトにするロケールを指定することもできます。たとえば、デフォルトのロケールをスイス・ドイツ語に切り替え、フランス語と英語を含めるには、次のオプションを使用します:

native-image -Duser.country=CH -Duser.language=de -H:IncludeLocales=fr,en

ロケールは言語タグを使用して指定します。-H:+IncludeAllLocalesを介してすべてのロケールを含めることができますが、結果の実行可能ファイルのサイズが大きくなることに注意してください。

リソース・バンドル

Javaローカライゼーション・サポート(java.util.ResourceBundle)を使用すると、JavaコードでL10Nリソースをロードし、時間、ロケール、書式などの実行時設定に適したユーザー・メッセージを表示できます。

ネイティブ・イメージでは、生成された実行可能ファイルでの使用に適したバンドルをロードおよび格納できるように、アプリケーションで必要なリソース・バンドルを事前に把握しておく必要があります。バンドルは、リソース構成ファイル(前述の説明を参照)のbundlesセクションで指定できます:

{
  "bundles": [
    {"name":"your.pkg.Bundle"},
    {"name":"another.pkg.Resource"},
    {"name":"etc.Bundle"}
  ],
  "resources": <see above>
}

または、次のようにバンドルをnative-imageツールのオプションとして直接指定することもできます:

native-image -H:IncludeResourceBundles=your.pgk.Bundle,another.pkg.Resource,etc.Bundle ...

デフォルトでは、要求されたすべてのロケールについて、要求されたバンドルが含められます。これを最適化するために、ロケール固有の部分文字列でIncludeResourceBundlesを使用できます。たとえば、-H:+IncludeResourceBundles=com.company.bundles.MyBundle_fr-FRでは、フランス語のバンドルのみが含められます。

Javaモジュールのリソース

リソースが<Java regexp that matches resources to be included in the image>で指定されているか、リソース・バンドルがバンドル名で指定されている場合、これらのリソースまたはバンドルを取得する必要があるモジュールを正確に指定できます。これを行うには、resource-regexまたはバンドル名の前にモジュール名を指定し、セパレータとして:を指定します。たとえば:

{
   "resources": {
      "includes": [
         {
            "pattern": "library-module:^resource-file.txt$"
         }
      ]
   },
   "bundles": [
      {"name":"main-module:your.pkg.Bundle"}
   ]
}

これにより、native-imageツールにJavaモジュールlibrary-moduleresource-file.txtのみが含まれるようになります。他のモジュールまたはクラスパスにパターン^resource-file.txt$に一致するリソースが含まれている場合、モジュールlibrary-module内のリソースのみが、実行可能ファイルに含めるように登録されます。同様に、同じバンドル名your.pkg.Bundleで他のバンドルにアクセスできる場合は、main-moduleのバンドルのみが含まれます。また、ネイティブ・イメージでは、モジュールが実行時にアクセス可能であることが保証されます。つまり、次のコード・パターンです:

InputStream resource = ModuleLayer.boot().findModule(moduleName).getResourceAsStream(resourcePath);

これは、前述のように登録されたリソースに対して常に期待どおりに機能します(モジュールに静的分析で到達可能と思われるコードが含まれていない場合でも)。

ローカライゼーションのJava VMモード

リソース・バンドル・ルックアップは、多くのJava VMインフラストラクチャを使用する複雑な動的メカニズムです。その結果、HelloWorldなどの小さいアプリケーションに対して実行可能ファイルのサイズが大きくなります。このため、デフォルトで最適化モードが設定され、すべてのバンドルが事前に認識されているという事実を利用してこのルックアップが簡略化されます。元のJava VMルックアップの場合は、-H:-LocalizationOptimizedModeオプションを使用します。

その他の情報