
要約
外部ライブラリ格納フォルダとクラスローダの関係は以下のようになります。
- Bootstrap class loader
- Extension class loader
domain-dir/lib/ext- Public API class loader
- Common class loader
domain-dir/lib- LifeCycleModule class loader
- Connector class loader
- Applib class loader
lib\applibs- Archive class loader
- Applib class loader
- Common class loader
- Public API class loader
- Extension class loader
domain-dir/lib/ext には、アプリケーションサーバ自体が必要とする拡張ライブラリを配備します。Java EE API に依存したライブラリなどは配備できません。
domain-dir/libには、JDBCドライバやカスタムログインモジュールやレルムなどのアプリケーションサーバで共通的に利用するライブラリを配備します。
lib\applibsには、デプロイ時に指定するアプリケーション用のライブラリを配備します。
各クラスローダの役割
Bootstrap class loader
JVMが提供する基本的なランタイム・クラスをロード。
Extension class loader
システム拡張ディレクトリdomain-dir/lib/ext に存在するJARファイルからクラスをロード。
Public API class loader
GlassFish Serverランタイムによってエクスポートされたすべてのクラスをロード。 Java EE API などが含まれる。
Common class loader
domain-dir/lib/classes 内のクラスファイル(.propertiesなども含む)、domain-dir/lib の JARファイルからクラスをロード(as-install/lib ディレクトリ内のJARファイルのロードも行うが、利用者がここを利用することは推奨されない)。
ロードの順序は as-install/lib domain-dir/lib/classes domain-dir/lib の順番。
JDBCドライバやカスタムログインモジュールとレルムはなどの JAR はここに配備する。
Connector class loader
個別にデプロイされたコネクターモジュールをロード。 すべてのアプリケーションで共有される。
LifeCycleModule class loader
ライフサイクル・モジュール毎に作成され、各ライフサイクル・モジュールのクラスパスを使用た独自のクラスローダとなる。
Applib class loader
展開時に指定された特定の有効モジュールまたは Java EE アプリケーション用のライブラリクラスをロード。 このクラスローダのインスタンスは、アプリケーション毎に1つ、個別にデプロイされた EAR JAR や Web WAR 毎に 1 つ存在する。 デプロイされた複数のアプリケーションが同じライブラリを使用する場合、ライブラリの同じインスタンスを共有する(ライブラリが別のライブラリのクラスを参照することはできない)。
Archive class loader
デプロイされたアプリケーションやモジュールのWAR、EAR、JARファイルやディレクトリ(ディレクトリ・デプロイの場合)からクラスをロード(スタブ・クラスやJSPページで生成されるサーブレットなど、GlassFish Serverランタイムが生成するアプリケーション固有のクラスも含む)。
add-library
asadmin コマンドの add-library で外部ライブラリを登録できます。
asadmin> add-library --type={ext|common|app} library-file-path [library-file-path ... ]
--type でそれぞれの格納先を制御できます。
ext を指定した場合 domain-dir/lib/ext に格納されます。
common を指定した場合 domain-dir/lib に格納されます。
app を指定した場合 lib\applibs に格納されます。
Logback 利用時の注意点
アプリケーションサーバ自身のロガーを変更したい場合、例えば以下のコマンドでロガーのハンドラを変更することができます。
asadmin> set-log-attributes "handlers=org.slf4j.bridge.SLF4JBridgeHandler"
このコマンドにより、domain-dir/config/logging.properties に以下が反映されます。
handlers=org.slf4j.bridge.SLF4JBridgeHandler
必要なライブラリJARは以下となります。 * slf4j-api-x.x.x.jar * jul-to-slf4j-x.x.x.jar * logback-core-x.x.x.jar * logback-classic-x.x.x.jar
これらは以下のコマンドで登録できます(直接フォルダに置いても同じです)。
asadmin> add-library --type=ext slf4j-api-x.x.x.jar jul-to-slf4j-x.x.x.jar logback-core-x.x.x.jar logback-classic-x.x.x.jar
しかしこの場合、logback-classic-x.x.x.jar は services を経由して ServletContainerInitializer に依存してしまっているので ClassNotFoundException になります。
詳細は以下を参照してください。
logback-classic-x.x.x.jar の中にある META-INF/services/javax.servlet.ServletContainerInitializer を削除すれば、一旦は対処することができます。