要約
外部ライブラリ格納フォルダとクラスローダの関係は以下のようになります。
- 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
を削除すれば、一旦は対処することができます。