以前WebOTX Application Server V8で動作していたEARが、WebOTX Application Server V9以降で動作しなくなりました。
現象としては、EAR内のclassesディレクトリに配置した設定ファイルがEAR内のlibディレクトリのjarファイルから参照できなくなっています。
EARの構成は以下の通りです。
app.ear
├─META-INF/
│ ├─MANIFEST.MF
│ └─application.xml
├─classes/
│ ├─foo.properties … [1]
│ └─bar.properties … [2]
├─lib/
│ └─common.jar … [3]
├─web-module.war … [4]
└─ejb-module.jar … [5]
[4]のWebモジュールが[3]のjar内のクラスを呼び出します。[3]のjar内のクラス(Foo)は[1]の設定ファイルを以下の方法で読み込もうとしますが、nullが返ります。
Foo.class.getClassLoader().getResourceAsStream(fileName);
[5]のEJBモジュールもclassesディレクトリの設定ファイル[2]を同様の方法で参照しますが、こちらは参照できています。
なお、[5]のEJBモジュールのマニフェスト(META-INF/MANIFEST.MF)ではClass-Path属性にclassesディレクトリを指定しています。
WebOTX Application Server V8とV9以降で動作が異なる理由とV9以降での対策を教えてください。
V8とV9以降の動作の違いの理由は、EAR用クラスローダの構成が変わったためです。
V8では、EAR内のlibディレクトリのjarファイル(common.jar)とEJBモジュール(ejb-module.jar)が同じクラスローダでロードされていました。
V8でのEARのクラスローダ構成は以下のようになります。
[EJBモジュール用クラスローダ] … lib/common.jar, ejb-module.jar, classes/ (ejb-module.jarのマニフェストより)
↑
[Webモジュール用クラスローダ] … web-module.war
lib/common.jarとclasses/(ejb-module.jarのマニフェストで指定)が同じクラスローダでロードされるため、lib/common.jarからclasses/のクラスやファイルを参照することができていました。
V9以降では、EAR内のlibディレクトリのjarファイル(common.jar)をロードするクラスローダが、EJBモジュール(ejb-module.jar)をロードするクラスローダとは別のクラスローダになりました。
V9以降では、EAR内のlibディレクトリのjarファイル(common.jar)はEJBモジュール(ejb-module.jar)よりも上位のクラスローダでロードされます。
V9以降でのEARのクラスローダ構成は以下のようになります。
[ライブラリ用クラスローダ] ……… lib/common.jar
↑
[EJBモジュール用クラスローダ] … ejb-module.jar, classes/ (ejb-module.jarのマニフェストより)
↑
[Webモジュール用クラスローダ] … web-module.war
lib/common.jarはclasses/(ejb-module.jarのマニフェストで指定)よりも上位のクラスローダでロードされるため、lib/common.jarからclasses/のクラスやファイルを参照することができなくなりました。
V9以降での対策としては、以下の2つの方法があります。
- 対策1. EAR内のclassesディレクトリのファイル(foo.properties, bar.properties)をjarファイルにアーカイブしてEAR内のlibディレクトリに配置する。(推奨)
この場合、EARのクラスローダ構成は以下のようになります。
[ライブラリ用クラスローダ] ……… lib/common.jar, lib/properties.jar (classesのファイルをアーカイブしたjarファイル)
↑
[EJBモジュール用クラスローダ] … ejb-module.jar
↑
[Webモジュール用クラスローダ] … web-module.war
- 対策2. EAR内のlibディレクトリのjarファイル(common.jar)のマニフェスト(META-INF/MANIFEST.MF)のClass-Path属性に「../classes」というクラスパスを追加する。
この場合、EARのクラスローダ構成は以下のようになります。
[ライブラリ用クラスローダ] ……… lib/common.jar, classes/ (lib/common.jarのマニフェストより)
↑
[EJBモジュール用クラスローダ] … ejb-module.jar
↑
[Webモジュール用クラスローダ] … web-module.war
【対象製品】Application Server
【確認済みのバージョン】V9以降
【確認済みのエディション】すべて
【確認済みの対象OS】すべて
【確認済みのJavaバージョン】すべて
【コンポーネント】配備
【カテゴリー】トラブルシューティング