ネイティブ・イメージでのリソースへのアクセス
デフォルトでは、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
の範囲(詳細が最も低いレベルから最も高いレベル)である必要があります。3
のlog level
では、含まれるリソースの簡単な詳細を説明します。
使用例
次のプロジェクト構造を考えます:
my-app-root
└── src
├── main
│ └── com.my.app
│ ├── Resource0.txt
│ └── Resource1.txt
└── resources
├── Resource2.txt
└── Resource3.txt
この場合、次のようになります:
- すべてのリソースは、構成ファイルで
{"pattern":".*/Resource.*txt$"}
として指定された".*/Resource.*txt$"
を使用するか、コマンドラインで-H:IncludeResources=".*/Resource.*txt$"
を使用してロードできます。 - Resource0.txtは、
.*/Resource0.txt$
を使用してロードできます。 - Resource0.txtおよびResource1.txtは、
.*/Resource0.txt$
および.*/Resource1.txt$
(またはかわりに1つの.*/(Resource0|Resource1).txt$
)を使用してロードできます。 - また、Resource2.txtファイル以外をすべて含める場合は、
-H:IncludeResources=".*/Resource.*txt$"
の後に-H:ExcludeResources=".*/Resource2.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-module
のresource-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
オプションを使用します。