BEA ホーム | 製品 | dev2dev | support | askBEA
 ドキュメントのダウンロード   サイト マップ   Glossary 
検索

WebLogic Server アプリケーションの開発

 Previous Next Contents Index PDF で侮ヲ  

WebLogic Server J2EE アプリケーション クラスローディング

以下の節では、Java クラスローダの概要、および WebLogic Server J2EE アプリケーションのクラスローディングについて説明します。

 


Java クラスローダの概要

クラスローダは、Java 言語の基本的コンポーネントです。クラスローダは、Java 仮想マシン (JVM) の構成要素で、クラスをメモリにロードし、実行時にクラス ファイルを検索してロードする役割を持つクラスです。Java プログラミングを適切に行うためには、クラスローダとその機能をよく理解する必要があります。この節では、Java クラスローダの概要を説明します。

Java クラスローダの階層

クラスローダには、親クラスローダと子クラスローダからなる階層があります。親クラスローダと子クラスローダの関係は、オブジェクトのスーパークラスとサブクラスの関係に似ています。ブートストラップ クラスローダは Java クラスローダ階層の親です。Java 仮想マシン (JVM) では、ブートストラップ クラスローダを作成し、このクラスローダによって、Java 開発キット (JDK) の内部クラスおよび JVM に組み込まれている java.* パッケージがロードされます (java.lang.String などがロードされます)。

拡張クラスローダは、ブートストラップ クラスローダの子です。拡張クラスローダは、JDK の拡張ディレクトリにあるすべての JAR ファイルをロードします。この機能は、クラスパスにエントリを追加することなく JDK を拡張できるので便利です。ただし、拡張ディレクトリ内にあるものは、すべて完全に独立している必要があり、拡張ディレクトリに含まれているクラスまたは JDK クラスしか参照できません。

システム クラスパス クラスローダは、JDK 拡張クラスローダを拡張します。システム クラスパス クラスローダは、JVM のクラスパスからクラスをロードします。アプリケーション固有のクラスローダ (WebLogic Server のクラスローダなど) は、システム クラスパス クラスローダの子です。

クラスのロード

クラスローダでは、クラスのロード時に委託モデルを使用します。クラスローダの実装では、まず要求されたクラスが既にロードされていないかチェックします。クラスを確認することで、ディスクからクラスを繰り返しロードする代わりに、キャッシュ メモリのコピーが使用されるのでパフォーマンスが向上します。メモリにクラスがないと、親クラスローダがクラスをロードします。親クラスローダがクラスをロードできない場合のみクラスローダはクラスのロードを試行します。親と子両方のクラスローダにクラスがあると、親のクラスがロードされます。

注意: クラスローダは、親クラスローダにクラスのロードを要求してから、クラスを実際にロードします。必要に応じて、ローカルでチェックをしてから親クラスローダをチェックするようにクラスローダをコンフィグレーションできます。

PreferWebInfClasses 要素

WebAppComponentMBean には、PreferWebInfClasses 要素があります。デフォルトでは、この要素は False に設定されています。この要素を True に設定すると、クラスローダの委託モデルが無効になり、Web アプリケーションおよびシステム クラスローダの両方にロードされる同じクラスの取得が容易になります。さらにそれにより ClassCastException の取得も容易になります。

この要素を True に設定して、さまざまなサービスの BEA 実装 (多くは XERCES などの XML 処理クラスの実装) をオーバーライドするユーザもいます。この要素を True に設定する場合には、異なるクラスローダからロードされたクラスのインスタンスが混在しないように注意してください。

コード リスト 3-1 PreferWebInfClasses 要素

/** 
* true の場合、Web アプリケーションの WEB-INF ディレクトリ内のクラスが、アプリケーションまたはシステム クラスローダにロードされるクラスに優先してロードされる 
* デフォルト値は false
*/ 
boolean isPreferWebInfClasses(); 
void setPreferWebInfClasses(boolean b);

実行中プログラムのクラス変更

WebLogic Server では、サーバが稼働中に EJB などのアプリケーション コンポーネントの新しいバージョンをデプロイできます。このプロセスは、ホットデプロイ、またはホット再デプロイと呼ばれ、クラスのロードと密接な関係があります。

新しいバージョンのアプリケーションをデプロイすると、新しいアプリケーション クラスローダが作成されます。この方法は、新しいクラスローダによってアプリケーション クラスがロードされている限り有効です。クラスがシステム クラスパスにある場合は、サーバの稼働中にクラスを変更することはできません。

注意: Java クラスローダには、クラスをアンデプロイしたり、アンロードしたりする標準メカニズムはありません。また、新しいバージョンのクラスをロードすることもできません。この問題を解決するため、クラスパス クラスローダの子としてアプリケーション固有のクラスローダを作成する方法があります。

 


WebLogic Server アプリケーションにおけるクラスローダの概要

この節では、WebLogic Server アプリケーション クラスローダの概要を説明します。

アプリケーションのクラスロード

WebLogic Server のクラスロードは、アプリケーションの概念に基づいています。アプリケーションは、通常、アプリケーション クラスを含むエンタープライズ アーカイブ (EAR) ファイルにパッケージ化されています。EAR ファイル内にあるものは、すべて同じアプリケーションの一部と見なされます。他に以下のアプリケーションがあります。

注意: リソース アダプタ RAR ファイルとそのクラスロードについては、リソース アダプタ クラス.を参照してください。

EJB の JAR ファイルと Web アプリケーションの WAR ファイルを別々にデプロイすると、これらは 2 つのアプリケーションと見なされます。2 つのファイルをまとめて EAR ファイル内にデプロイすれば、1 つのアプリケーションとなります。したがって、複数のコンポーネントが同一アプリケーションの一部と見なされるためには、複数のコンポーネントをまとめて EAR ファイルにデプロイします。

リソース アダプタ固有のクラスが WebLogic Server のシステム クラスパスにないことを確認してください。リソース アダプタ固有のクラスを Web コンポーネント (EJB、Web アプリケーションなど) と共に使用する必要がある場合、それらのクラスを該当するコンポーネントのアーカイブ ファイル (EJB に使用する JAR ファイルまたは Web アプリケーションに使用する WAR ファイルなど) にまとめます。

すべてのアプリケーションは、独自のクラスローダ階層を受け取ります。この階層の親はシステム クラスパス クラスローダです。したがって、アプリケーションどうしが隔離されているため、アプリケーション A からアプリケーション B のクラスローダおよびクラスを見ることはできません。クラスローダには、兄弟概念またはフレンド概念はありません。アプリケーション クラスローダから見ることができるのは、親クラスローダであるシステム クラスパス クラスローダだけです。したがって、WebLogic Server は同一の JVM 内の複数の隔離されたアプリケーションのホストになります。

アプリケーション クラスローダの階層

WebLogic Server では、アプリケーションのデプロイ時にクラスローダのセットが自動的に作成されます。基本アプリケーション クラスローダによって、アプリケーション内の EJB JAR ファイルがロードされます。また、Web アプリケーション WAR ファイルごとに子クラスローダが作成されます。

Web アプリケーションによる EJB の呼び出しがよくあるため、WebLogic Server アプリケーション クラスローダ アーキテクチャでは JavaServer Page (JSP) ファイルおよびサーブレットからその親クラスローダ内の EJB インタフェースを見ることができるようになっています。また、このアーキテクチャでは EJB 層を再デプロイすることなく Web アプリケーションを再デプロイできます。実際には、EJB 層ではなく JSP ファイルおよびサーブレットを変更するほうが一般的です。

次の図は、WebLogic Server アプリケーションのクラスロード概念を示しています。

図3-1 WebLogic Server のクラスロード


 


 

アプリケーションに EJB を使用するサーブレットと JSP が含まれる場合は、次の手順に従います。

WAR ファイルと JAR ファイルは別々にデプロイできますが、まとめて 1 つの EAR ファイルにしてデプロイすることにより、サーブレットと JSP から EJB クラスを検索できるようにクラスローダが配置されます。WAR ファイルと JAR ファイルを別々にデプロイすると、WebLogic Server ではそれらのファイルごとに兄弟のクラスローダを作成します。したがって、その WAR ファイルには EJB ホームおよびリモート インタフェースを含める必要があります。WebLogic Server では、EJB クライアントと実装クラスが異なる JVM にある場合と同じように、EJB 呼び出しに RMI のスタブ クラスとスケルトン クラスを使用します。この概念については、次節のアプリケーション クラスロードと、値渡しまたは参照渡しで詳しく説明しています。

注意: Web アプリケーション クラスローダには、サーブレット実装クラスと JSP クラスを除く、Web アプリケーションのすべてのクラスが含まれます。各サーブレット実装クラスと JSP クラスは、独自のクラスローダを取得します。このクラスローダは Web アプリケーション クラスローダの子です。これにより、サーブレットと JSP を個別に再ロードできます。

アプリケーション クラスロードと、値渡しまたは参照渡し

最近のプログラミング言語では、パラメータを渡すときのモデルとして、値渡しと参照渡しがよく使用されます。値渡しの場合、パラメータおよび戻り値はメソッドの呼び出しごとにコピーされます。参照渡しの場合は、実際のオブジェクトを示すポインタ (または参照) がメソッドに渡されます。参照渡しでは、オブジェクトをコピーしなくてもよく、渡されたパラメータの状態を変更するメソッドも使用できるため、パフォーマンスが向上します。

WebLogic Server では、サーバ内のリモート メソッド インタフェース (RMI) 呼び出しのパフォーマンス向上のための最適化機能もあります。値渡しおよび RMI サブシステムのマーシャリングやアンマーシャリング機能を使用するのではなく、参照渡しを使用することによって、サーバがダイレクト Java メソッド呼び出しを行います。この方式により、パフォーマンスが大幅に改善され、EJB 2.0 ローカル インタフェースにもこの方式が採用されています。

RMI 呼び出しの最適化および参照呼び出しが使用されるのは、呼び出す側と呼び出される側が共に同じアプリケーションにある場合に限られます。通常、クラスローダが関係します。アプリケーションにはそれぞれ独自のクラスローダ階層があるため、どのアプリケーション クラスも両方のクラスローダに定義があり、複数のアプリケーション間で割り当てを行おうとすると ClassCastException エラーを受け取ります。この問題を回避するため、WebLogic Server では複数のアプリケーション間での呼び出しには、同じ JVM 内であっても値呼び出しを使用しています。

注意: 複数アプリケーション間の呼び出しは、同一アプリケーション内の呼び出しに比べて遅くなります。したがって、コンポーネントは 1 つの EAR ファイルにまとめてデプロイし、高速の RMI 呼び出しおよび EJB 2.0 ローカル インタフェースを使用できるようにしてください。

以下に EJB バージョン 2.0 および 1.1 で呼び出されるパラメータの値渡しと参照渡しのリストを示します。

表3-1 EJB バージョン 2.0 で呼び出されるパラメータ

パッケージ化

呼び出される側のインタフェース

デフォルトの呼び出しタイプ

enable-call-by-reference の影響

呼び出す側の WebApp/EJB が EAR ファイルにある

ローカル


リモート

参照渡し


値渡し

False の場合、値渡し


True の場合、参照渡し

呼び出す側の EJB と呼び出される側の EJB が同じ EAR ファイルではなく、同じ JAR ファイルにある

ローカル


リモート

参照渡し


値渡し

False の場合、値渡し


True の場合、参照渡し

呼び出す側の WebApp/EJB と呼び出される側の EJB が別々のデプロイメント モジュール (EAR/JAR) にある

ローカル


リモート

値渡し


値渡し

なし


なし

表3-2 EJB バージョン 1.1 で呼び出されるパラメータ

パッケージ化

呼び出される側のインタフェース

デフォルトの呼び出しタイプ

enable-call-by-reference の影響

呼び出す側の WebApp/EJB が EAR ファイルにある

リモート

参照渡し

False の場合、値渡し


呼び出す側の EJB と呼び出される側の EJB が同じ EAR ファイルではなく、同じ JAR ファイルにある

リモート

参照渡し

False の場合、値渡し


呼び出す側の WebApp/EJB と呼び出される側の EJB が別々のデプロイメント モジュール (EAR/JAR) にある

リモート

値渡し

なし

 


コンポーネントおよびアプリケーション間のクラス参照の解決

アプリケーションでは、エンタープライズ Bean、サーブレットと JavaServer Pages、ユーティリティ クラス、およびサード パーティ製パッケージなど、さまざまな Java クラスを使用します。WebLogic Server では、個別のクラスローダにアプリケーションをデプロイして、独立を維持し、動的な再デプロイメントとアンデプロイメントを容易にします。このため、各コンポーネントが各クラスに個別にアクセスできるようにアプリケーションのクラスをパッケージ化する必要があります。場合によっては、一連のクラスを複数のアプリケーションまたはコンポーネントに格納する必要があります。この節では、アプリケーションを正常にステージングするために、WebLogic Server で複数のクラスローダを使用する方法について説明します。

リソース アダプタ クラス

リソース アダプタ固有のクラスが WebLogic Server のシステム クラスパスにないことを確認してください。リソース アダプタ固有のクラスを Web コンポーネント (EJB、Web アプリケーションなど) と共に使用する必要がある場合、それらのクラスを該当するコンポーネントのアーカイブ ファイル (EJB に使用する JAR ファイルまたは Web アプリケーションに使用する WAR ファイルなど) にまとめます。

共有ユーティリティ クラスのパッケージ化

複数のアプリケーションでユーティリティ クラスを共有していることがよくあります。複数のアプリケーションで使用するユーティリティ クラスを作成または取得する場合、そうしたクラスは各アプリケーションと共に個別の JAR ファイルにパッケージ化します。JAR ファイルは、完全に独立している必要があり、EJB または Web コンポーネント内のクラスへの参照はありません。共有ユーティリティ クラスとして一般的なものはデータ転送オブジェクトまたは JavaBean で、Web 層と EJB 層の間で受け渡しされます。

代わりに、WebLogic Server を実行するスクリプト内の java コマンドを編集して、Java システム クラスパスに共有ユーティリティ クラスを追加できます。ただし、ユーティリティ クラスを変更し、そのクラスが Java システム クラスパスにある場合は、ユーティリティ クラスを変更した後に WebLogic Server を再起動する必要があります。

起動時に WebLogic Server が使用するクラスは Java システム クラスパスに存在しなければなりません。たとえば、接続プールに使用する JDBC ドライバは WebLogic Server の起動時にクラスパス内になければなりません。また、Java システム クラスパス内のクラスを変更する必要がある場合、またはクラスパスを変更した場合は、クラスまたはクラスパスを変更した後に WebLogic Server を再起動する必要があります。

マニフェスト クラスパス

J2EE 仕様では、クラスの補助的な JAR ファイルを必要とすることをコンポーネントで指定する手段としてマニフェスト Class-Path エントリが用意されています。このマニフェスト Class-Path エントリを使用するのは、EJB JAR ファイルまたは WAR ファイルの一部として追加の補助的な JAR ファイルがある場合に限られます。その場合、JAR ファイルまたは WAR ファイルの作成時に、必要な JAR ファイルを参照する Class-Path 要素と共にマニフェスト ファイルを含める必要があります。

utility.jar ファイルを参照する簡単なマニフェスト ファイルを以下に示します。

Manifest-Version: 1.0 [CRLF]
Class-Path: utility.jar [CRLF]

このマニフェスト ファイルの先頭行には、常に Manifest-Version 属性を指定する必要があり、次に改行 (CR | LF |CRLF)、そして Class-Path 属性が続きます。マニフェスト フォーマットの詳細については、http://java.sun.com/j2se/1.4/docs/guide/jar/jar.html#JAR を参照してください。

マニフェスト Class-Path エントリは、エントリが定義されている現在のアーカイブを基準として他のアーカイブを参照します。この構造により、複数の WAR ファイルおよび EJB JAR ファイルで、共通のライブラリ JAR を共有できます。たとえば、WAR ファイルに y.jar というマニフェスト エントリが含まれる場合、このエントリは、次のように WAR ファイルの次に (中ではない) 指定されなければなりません。

/<directory>/x.war
/<directory>/y.jars

マニフェスト ファイル自体は、META-INF/MANIFEST.MF のアーカイブに配置します。

詳細については、http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html を参照してください。

 

Back to Top Previous Next