昨今、Javaアプリケーションのコンテナ / Serverless利用が増加する中で、「アプリケーション起動速度」はパフォーマンス・運用コストの両面でますます重要になっています。
WebSphere Liberty / Open Libertyのように軽量・モジュール化されているJavaランタイムを活用する場合でも、CDI やアノテーションベースのJakarta EEアプリは起動時に大量のクラススキャンを行うため、どうしても時間がかかりがちです。
そこで注目されているのが、Javaクラスファイルを効率的にインデックス化し、実行時に高速なメタデータ取得を可能にするJandexです。
本記事では、Jandexの概要と、Libertyにおける最新のJandexサポートをまとめます。
なぜJakarta EEアプリの起動は遅いのか?
Jakarta EE/Java EEアプリは起動時に以下のクラス探索を行います:
・CDIのBean Discovery
・JPAのエンティティ探索
・ServletContainerInitializerの探索
これらは共通して「クラススキャン」に依存しており、次のような特性があります。
・クラス数に比例して処理が重くなる
・バイトコード解析やIOが多い
・コンテナ環境では起動回数が多く、遅延が顕著になる
Jandex とは
Jandex(Java Annotation Indexer)は、Javaクラスのアノテーションや型情報をビルド時に解析し、「jandex.idx」としてインデックス化するOSSライブラリです。実行時にはクラススキャンを行う代わりに、このインデックスを直接参照して必要なメタデータを取得します。
これにより、従来のバイトコードスキャンを大幅に削減でき、起動時間の短縮が期待できます。Libertyでは通常、アプリケーション内の全クラスをスキャンしてメタデータを取得しますが、大規模アプリケーションではこの処理がボトルネックとなる場合があります。
そのため、Libertyではアプリケーション内に配置されたJandexインデックス(META-INF/jandex.idx)が存在する場合、クラススキャンをスキップし、インデックスを優先的に利用する仕組みが提供されています。
Libertyにおける動作イメージ
アプリケーション内の各WAR/JARにjandex.idxが存在するかを確認し、
存在する場合はインデックスを読み取り、メタデータを取得
存在しない場合は従来通りバイトコードスキャンを実施
という動作となります。
すなわち、「インデックス化された部分のみを高速化する」ハイブリッドモデルとなっています。
さらに、2026年のOpen Liberty 26.0.0.3では、Index Format 11〜13(Jandex 3.1.0〜3.5.3相当)が公式にサポートされました。
https://openliberty.io/blog/2026/03/24/26.0.0.3.html
これにより、Quarkus/SmallRye/MicroProfileなどJandex 3.x系で生成されるインデックスをそのままLibertyで利用できるようになり、互換性が向上しています。
実際の設定方法
1. Jandex index(jandex.idx)の配置場所
全アーカイブ共通の配置先は以下の通りです。
META-INF/jandex.idx
WARの場合の例:
App.war/
├── META-INF/
│ └── jandex.idx
├── WEB-INF/
│ ├── classes/
│ └── lib/
│ └── someLib.jar
│ └── META-INF/
│ └── jandex.idx
※WAR内部のJARにも個別にjandex.idxの配置が必要です(WAR全体をまとめた単一indexはサポートされていません)。
2. Liberty 側の設定
server.xmlにて下記の設定を追加
すべてのアプリで Jandex を有効化する場合:
<applicationManager autoExpand="true" useJandex="true"/>
特定アプリだけ有効化する場合:
<application location="SampleApp.war" type="war" useJandex="true"/>
Jandex 導入によるパフォーマンス改善の実例
IBMの公式ドキュメントでは、最大40%の起動時間短縮が期待できるとされています。
https://www.ibm.com/support/pages/using-jandex-ibm-websphere-liberty-overview
実際に、Jandex導入の有無によるOpen Libertyの起動時間を比較しました。検証には、AIエージェント開発ツールIBM Bobで作成した書籍管理アプリケーションを使用しています。
クラススキャン対象は以下の通りです。
- CDI Bean Discovery対象(209クラス)
- JPA Entity Scanning対象(65クラス)
- ServletContainerInitializer対象(1クラス)
Jandex非導入の場合
まず、Jandexを導入していない状態でサーバーおよびアプリケーションを起動した場合の結果は以下の通りです。
| 指標 | 時間 |
|---|---|
| カーネル起動 | 1.417秒 |
| Feature初期化 | 8.186秒 |
| アプリケーション起動 | 3.959秒 |
| サーバー準備完了 | 9.603秒 |
Jandex導入後の場合
次に、Jandexプラグインを用いてインデックスファイル(jandex.idx)を生成後、同様の条件下でアプリケーションを起動しました。
Liberty起動時には、以下のログからJandexインデックスが読み込まれていることを確認できます。
[2026/04/17 18:24:44:092 JST] 0000003c com.ibm.ws.annocache I CWWKC0093I: アプリケーション app-quick でのモジュール app-quick の Jandex カバレッジ: 1 のうち 1 のモジュール・ロケーションの Jandex インデックスが読み取られました。Jandex インデックスは 209 のうち 209 のモジュール・クラスを提供しました。
この状態での起動時間は以下の通りです。
| 指標 | 時間 |
|---|---|
| カーネル起動 | 0.612秒 |
| Feature初期化 | 5.807秒 |
| アプリケーション起動 | 3.539秒 |
| サーバー準備完了 | 6.420秒 |
結果比較
| 指標 | 非導入 | 導入後 | 短縮量 | 削減率 |
|---|---|---|---|---|
| カーネル起動 | 1.417秒 | 0.612秒 | -0.805秒 | 約57% |
| Feature初期化 | 8.186秒 | 5.807秒 | -2.379秒 | 約29% |
| アプリ起動 | 3.959秒 | 3.539秒 | -0.420秒 | 約11% |
| サーバー準備完了 | 9.603秒 | 6.420秒 | -3.183秒 | 約33% |
サーバー準備完了までの時間を比較すると、約33%の起動時間短縮が確認でき、IBM公式ドキュメントで言及されている「最大40%短縮」に近い実測値が得られました。
特に Feature初期化フェーズでの削減効果が顕著であり、Jandex 導入によってアノテーションスキャン時の I/O およびリフレクション負荷が大幅に削減されていることが分かります。
これは、事前生成されたインデックスを活用することでランタイム中のクラススキャンを最小化するという、Jandex 本来の設計意図どおりの挙動が実際の数値として現れた結果と言えます。
まとめ
Jandexは、Jakarta EEアプリの起動時に発生する重いクラススキャンをビルド時に置き換えることで、起動時間を大きく短縮できる実践的な技術です。そして、LibertyはJandex3.x系のインデックスにも対応し、モダンJavaスタックとの互換性がさらに向上しました。
コンテナ/Serverless時代のLibertyアプリ最適化として、非常に有効な選択肢と言えるでしょう。
本投稿をご覧いただき、ありがとうございました。