JBossのクラスローダについての解説
ClassLoadingConfigurationの翻訳(今のところ途中まで)
◆概要
デフォルトではJBoss(3.2.x以下)はフラットなクラスローディングモデルを使うので,異なる層でクラスを冗長に持つ必要が無い。WARはWebのコンテンツ,サーブレット,EJB(とそのインターフェース,impl,typeなど)のみを含むべきである。正規のパッケージングは,このモデルの元で動作する。
しかしながら,これはフラットタイプシステムが全てのデプロイされたアプリケーションに適用されると仮定している。もしバージョン間の非互換のためクラスを共有できない場合,他のアプリケーションからクラスのスコープを分ける必要がある。これが必要となる一般的な症状はClassCastException,IllegalAccessError,VerufyErrorなどであり,だいたい新しいデプロイメントの追加や削除時に変化する奇妙なふるまいである。
スコープには2種類ある。他のデプロイメントからの分離と,サーパクラスのオーバライドを伴う分離である。トップレベルのデプロイメントだけが分離(isolation)を指定できる。他のモジュールを持つEARの場合,EARのMETA-INF/jboss-app.xmlに指定されたスコープだけが有効になる。このルールは,デプロイディレクトリにあるデプロイメントにも適用される。もしSARが他のデプロイメントを含んでいれば,SARのMETA-INF/jboss-app.xmlのスコーピング指定だけが有効である。
◆分離(Isolation)
jboss-app.xmlに,以下の記述を追加することで,スコープ化されたクラスローディングを有効にして,他のアプリケーションからクラスを分離できる。
dot.com:loader=unique-archive-name
jboss-web.xmlの場合には,以下のように記述する。
dot.com:loader=unique-archive-name
これらは対応するjboss-app,jboss,jboss-webのルート要素中に正しく記述する必要があるので,docs/dtdディレクトリにある対応するdtdをチェックすること。
◆オーバライド付き分離
jboss-app.xmlで以下のように記述することで,スコープ化されたクラスローディングを有効にして,サーバクラスをオーバロードするように指定できる。
dot.com:loader=unique-archive-name java2ParentDelegation=false
... dot.com:loader=unique-archive-name java2ParentDelegation=false
dot.com:loader=unique-archive-nameはJMXのObjectName文字列で,ユニークなクラスローディングスコープを保証するために,ユニークな文字列でさえあればいい。EAR/WARファイルに使われているのと同じ名前を使っておくと便利である。
loader-repositoryはJBossのJMX-Console(http://localhost:8080/jmx-console/)に表示され,クラスローディングの問題をデバッグするのに有用である。階層型ローダはloader-repository名(例では"dot.com")でグループ化されている。
分離されたEAR/WARのリポジトリは,ライブラリを以下の順番で読み込む。
以下は間違っている]]。APP-INF/libはWeblogic固有である。*1
- APP-INF/lib(EARの場合)とWEB-INF/lib(WARの場合)
- server/default/lib
- server/default/deploy/jbossweb-tomcat50.sarにあるtomcatのライブラリ(JBoss3.2.6)
server/default/libのライブラリはjbossweb-tomcat50.sarにあるライブラリと優先順位なしに混在することになる(詳細はJMX-consoleのloader-repositoryで確認せよ)。
◆Webコンテナ
JBoss3.2.3では,jbossweb-tomcat41.sarがクラスローダとして統合クラスローダを使うように設定されている。これはjbossweb-tomcat41.sar/META-INF/jboss-service.xmlのUseJBossWebLoader属性によってコントロールされている。統合クラスローダの利用は,WARのWEB-INF/classesとWEB-INF/jarsにあるクラスが,デフォルトの共有クラスローダリポジトリに含まれることを意味している。これはあなたの望むことではないかもしれない。なぜならこれはサーブレット3.2のデフォルトのローディングモデルとは逆で,Webアプリ間でクラスやリソースが共有されることになるからだ。UseJBossWebLoader属性をfalseにすれば,無効化できる。
◆4.0.2以降のWebコンテナ
JBossの4.0.2からは,サーブレット仕様のクラスローディングモデルに変更されている。つまりTomcatのクラスローダを使用している。
◆3.2.4以降の簡単設定
JBoss3.2.4以降,EARのデプロイ記述子には分離のための簡易版が用意されている。リモートインターフェースに値呼び(call-by-value)を使うことで,全てのEARが分離されたクラスローダ空間を持つようにできる。
バージョン3.xのEARの記述子はconf/jboss-service.xml,バージョン4.xではdeply/ear-deployer.xmlで設定される。
<!-- EAR deployer, remove if you are not using Web layers --> <mbean code="org.jboss.deployment.EARDeployer" name="jboss.j2ee:service=EARDeployer"> <!-- Isolate all ears in their own classloader space --> <attribute name="Isolated">true</attribute> <!-- Enforce call by value to all remote interfaces --> <attribute name="CallByValue">true</attribute> </mbean>
◆分離されたEAR内のEJBを呼び出す
(ここからはEJBの話。翻訳した方がいいかなあ?)
*1:こんなこと書かれてもなあ。じゃー直せよー