オープン・ソース・ソフトウェア・パッケージの分離

いくつかの方法を使用して、 Java™ Platform, Enterprise Edition (Java EE) アプリケーションおよびその他の Java EE デプロイ可能成果物をオープン・ソース・ソフトウェア (OSS) パッケージから分離することができます。 これらのメソッドを適用して、 WebSphere® Application Server に組み込まれている OSS パッケージの使用時に発生する可能性があるクラス・ロード・エラーおよび予期しないランタイム動作を解決します。

「オープン・ソース・ソフトウェア API」 トピックには、 WebSphere Application Server によって提供される、アプリケーションでの使用を意図した OSS パッケージがリストされており、それらの使用に関する資料への参照が記載されています。

Java EE アプリケーションで、アプリケーションの直接使用を意図した OSS パッケージに関する問題が発生した場合は、対応する使用法の資料を参照して、アプリケーションとサーバーが正しく構成されていることを確認してください。 例えば、アプリケーションが Apache Commons ロギングに関連するクラス・ロードの問題を検出した場合は、 Jakarta Commons Logging のトピックを参照してください。

アプリケーションが直接アプリケーションで使用することを意図していない OSS パッケージに関する問題を検出した場合は、このトピックに含まれている 「OSS パッケージから Java EE アプリケーションを分離するためのベスト・プラクティス」 セクションを参照して、 WebSphere Application Serverで提供されている同じパッケージにリンクする際にアプリケーション用に提供されている OSS パッケージを保護する方法を確認してください。

他の Java EE 成果物を分離する方法は少なくなります。 スタンドアロンのリソース・アダプターおよびリソース・プロバイダーには、分離を使用可能にする構成オプションがあります。 WebSphere Application Serverに組み込まれている OSS パッケージで問題が発生したスタンドアロン・リソースについては、 分離されたリソース・プロバイダーに関する考慮事項 のトピックを参照して、リソースの分離が実行可能かどうかを判別してください。 可能であれば、オプションを設定してください。 サーバーが再始動されると、ランタイムは、 「parent_last」の委任が構成された別のクラス・ローダーとリソース・クラスパスを使用してリソースをロードします。

リソース分離が不可能な場合、または障害のある Java EE 成果物がリソースでない場合は、この資料の「 常時保護 (分離) パッケージの構成 」セクションで説明されている方法を使用して、問題のある OSS パッケージから成果物を分離してください。

OSS パッケージから Java EE アプリケーションを分離するためのベスト・プラクティス

WebSphere Application Serverに組み込まれている OSS パッケージからアプリケーションを保護するには、共有ライブラリー、 parent_last クラス・ローダー委任、または必要に応じて常に保護されたパッケージを使用します。

分離された共有ライブラリー

WebSphere Application Server に組み込まれている OSS パッケージからアプリケーションを分離するための理想的な方法は、パッケージを独立した共有ライブラリーとしてデプロイし、それをすべての従属アプリケーションおよび Web アプリケーション・アーカイブ (WAR) モジュールに関連付けることです。 この方法では、ライブラリーに関連付けられたアプリケーションと WAR モジュールだけが OSS パッケージを使用できるようになります。 実行時に、分離された共有ライブラリーのクラスが、固有のクラス・ローダー・インスタンスからロードされます。 その際には、確実に、OSS クラスがライブラリー・ローダーから即時にロードされ、ライブラリー・クラスが、そのライブラリーを共有するすべてのアプリケーションで一度定義されます。

アプリケーションまたは WAR モジュールに関連付けられた、それぞれの分離された共有ライブラリーについて、 サーバー・ランタイムはクラス・ローダーを作成してライブラリーのクラスパスで構成し、 それを内部委任として、対応するアプリケーションおよび WAR クラス・ローダーに接続します。 クラスのロード時に、アプリケーションおよび WAR モジュールのクラス・ローダーのクラス・ローダー (委任) モードは、これらのローダーが WebSphere Application Server クラス・ローダー階層内でアプリケーション・クラスを検索する順序を決定します。 1 つ以上の分離された共有ライブラリーがアプリケーションまたは WAR モジュールに関連付けられており、対応するクラス順序の委任モード (例えば、 myAppCL) が Classes loaded with the parent class loader first (Parent_first)に設定されている場合、メソッド myAppCL.loadClass(clsName) は以下の順序で clsName を検出します。
  1. JVM クラス・キャッシュで定義済みクラス <myAppCL, clsName> を検索します。
  2. 関連付けられたそれぞれの分離されたライブラリー・クラス・ローダーのクラスパスで clsName を検索します。
  3. loadClass(clsName)myAppCL の親クラス・ローダーに委任します。
  4. myAppCL のクラスパスで clsName を検索します。
委任モードが Classes loaded with the parent class loader last (Parent_last)に設定されている場合、メソッド myAppCL.loadClass(clsName) は以下の順序で clsName を検出します。
  1. JVM クラス・キャッシュで定義済みクラス <myAppCL, clsName> を検索します。
  2. myAppCL のクラスパスで clsName を検索します。
  3. 関連付けられたそれぞれの分離されたライブラリー・クラス・ローダーのクラスパスで clsName を検索します。
  4. loadClass(clsName)myAppCL の親クラス・ローダーに委任します。

関連する共有ライブラリーは、モジュール・クラス・ローダーが親に委任する前に常に検索されるため、このメソッドは、 myAppCLParent_first または Parent_lastのどちらに構成されているかに関係なく機能します。

サーバー共有ライブラリー

アプリケーションから OSS パッケージを分離する別の方法として、 サーバー構成で定義されたクラス・ローダーに共有ライブラリーを関連付ける方法があります。 サーバー定義のクラス・ローダーの委任モードは、 Parent_lastに設定する必要があります。 この方法では、アプリケーションおよび WAR モジュールのクラス・ローダーがすべて、少なくとも 1 つの親に loadClass() を委任して、ライブラリーのクラスをロードする必要があります。 そのため、この方法より、分離された共有ライブラリーを使用する方法のほうが推奨されます。

共有ライブラリーを作成および構成する方法については、「 共有ライブラリーの管理 」トピックを参照してください。

クラス・ローダーの委任

共有ライブラリーを使用できない場合、 アプリケーション内の依存関係 JAR として OSS パッケージをアセンブルします。 アプリケーションがインストールされたら、OSS パッケージをロードするアプリケーションおよび WAR モジュールのクラス・ローダーごとに、クラス・ロード (委任) モードを Parent_last に設定します。 この方法では、 分離された共有ライブラリー・クラス・ローダーがクラスを定義して、 同じクラス・ローダーを使用する従属クラスを JVM がロードした場合に、 他のアプリケーション、WAR モジュール、およびサーバー定義のクラス・ローダーで従属クラスは検出されません。 そのため、この方法より、分離された共有ライブラリーを使用する方法のほうが推奨されます。

クラス・ロード 」トピックでは、アプリケーションおよび WAR モジュールのクラス・ローダーの委任モードを設定する方法について説明します。

上記の方法がどれも可能でない場合は、 次のセクションで説明されている『常時保護 (分離) パッケージの構成』を試してください。

常時保護 (分離) パッケージの構成

WebSphere Application Server は、 WebSphere Application Server クラス・ローダー階層内の OSGi ゲートウェイの下にあるすべてのクラス・ローダーから隠蔽される 常時保護 (または 分離) パッケージ名のリストを保持します。 常時保護パッケージを構成して、すべての Java EE デプロイ済み成果物を、 WebSphere Application Serverに組み込まれている OSS パッケージから分離します。

常時保護パッケージは、アプリケーションおよび共有ライブラリー・クラス・ローダーの論理親である WebSphere Extensions Classloader (ExtClassLoader) が、ロード操作を OSGi ゲートウェイに委任するかどうかを制御します。 OSS パッケージは OSGi ゲートウェイによって可視になるため、ゲートウェイへの委任を実質的に防止することで、 Java EE アプリケーションおよび共有ライブラリーが、常時保護として宣言された OSS パッケージに予期せずにリンクするのを防ぐことができます。 この機能は、ExtClassLoader クラスパスから直接ロードするデプロイ済み成果物もサポートします。 これには、非分離として構成されたスタンドアロン・リソース・アダプターおよびプロバイダー、カスタム・サービス、およびカスタム認証モジュールが含まれます。

常時保護パッケージを使用して、 WebSphere Application Server 機能を妨げるパッケージを指定することはできません。 禁止されるパッケージには、{"java.", "com.", "com.ibm."} が含まれます。 常時保護リソースのパスを構成することもありますが、その可能性はあまりありません。 禁止されているリソース名には {"java/", "com/", "com/ibm/", "META-INF/services/"}があります。 サーバーは、これらの入力と、構文的または意味的に無効な入力を無視します。

以下の手順は、アプリケーションとその他の成果物の両方が同じ OSS パッケージを提供する場合に機能しないことがあります。 1 つの OSS パッケージをアプリケーションとスタンドアロン・リソース・アダプター (非分離として構成) の両方が提供する場合に、どちらもリソース・アダプター提供のパッケージにリンクしていて、ExtClassLoader クラスパスで可視であることがあります。 このようなデプロイメントでは、スタンドアロン・リソース・アダプターを分離として再構成するか、前述の提案をアプリケーション・デプロイメントに適用する必要があります (例えば、アプリケーション・クラス・ローダー委任モードを Parent_last に設定したり、分離された共有ライブラリーをアプリケーションに関連付けたりします)。 常時保護パッケージはデフォルトで使用可能になり、使用不可にすることはできません。 常時保護パッケージのリストには、常に追加が可能です。

  1. 問題となる OSS フレームワークのルート・パッケージ名を判別します。 例えば、Apache HTTP コンポーネントのルート・パッケージ名は org.apache.http. です。 Apache HTTP コンポーネント内のすべてのクラスは、接頭部としてこのルート・パッケージ名を持っています。 詳しくは、 オープン・ソース・ソフトウェア API のトピックを参照してください。
  2. 管理コンソールの「サーバー設定」ページの「サーバー・インフラストラクチャー」で、 「Java およびプロセス管理」 > 「プロセス定義」をクリックします。
  3. Java 仮想マシン」を選択します。
  4. JVM 汎用引数セクションで次のようにシステム・プロパティーを定義します。
    1. システム・プロパティー -Dws.ext.debug=true を定義します。
    2. JVM 汎用引数でシステム・プロパティー -Dcom.ibm.ws.classloader.server.alwaysProtectedPackages=<pkg1>,...,<pkgN> を定義して、デプロイされた Java EE 成果物から OSS パッケージ <pkg1>...<pkgN> を非表示にします。 この設定だけで、問題となる OSS パッケージは隠されるはずです。
      常時保護パッケージ: com.ibm.ws.classloader.server.alwaysProtectedPackages

      WebSphere Application Server がすべてのデプロイ済み成果物から分離 (保護) するパッケージ名のコンマ (',') 区切りストリング。 常時保護パッケージ名は、'.' で終わる必要があり、禁止されているパッケージ名のサブパッケージであってはなりません。 WebSphere Application Server は、無効な常時保護パッケージ名を無視します。

      このプロパティーが設定されると、ExtClassLoader リソース API の getResource(rscName) は、clsName に接頭部として常時保護パッケージ名が含まれる場合、OSGi ゲートウェイに委任しません。 clsNameExtClassLoader のローカル・クラスパスで可視である場合にのみ、このメソッドはクラスを戻します。 同様に、リソース名が .class で終わり、パス内にある場合、 ExtClassLoader リソース API は OSGi ゲートウェイに委任しません。 パッケージ名への変換後には、接頭部として常時保護パッケージ名が含まれます。

      例えば、パッケージ名 org.oss.pkg. が常時保護である場合、 ExtClassLoader.loadClass(org.oss.pkg.Unexpected) OSGi ゲートウェイに委任せず、事実上、 すべての JEE アプリケーション、共有ライブラリー、カスタム認証モジュール、スタンドアロン・リソース、およびカスタム・サービスが パッケージ org.oss.pkg. 内のクラスに予期せずリンクすることがなくなります。

      同様に、メソッド ExtClassLoader.getResource(org/oss/pkg/Unexpected.class) は OSGi ゲートウェイに委任しません。さらに、デプロイされた成果物が、 WebSphere Application Serverによって提供される org.oss.pkg. パッケージ内のクラス・ファイルをディスカバーできないようにします。

      デフォルト値は unsetです。

    3. デプロイされた成果物が、 WebSphere Application Serverに組み込まれている OSS パッケージによって提供されるリソースを予期せずにロードする場合は、システム・プロパティー -Dcom.ibm.ws.classloader.server.alwaysProtectedResources=<rsc>,...,<rscN> を定義して、デプロイされた成果物から OSS リソース・パス <rsc>...<rscN> を隠すようにします。
      常時保護リソース: com.ibm.ws.classloader.server.alwaysProtectedResources

      WebSphere Application Server がすべてのデプロイ済み成果物から分離 (保護) する、 ','で区切られたリソース名のストリング。 常時保護リソース名は、'/' で始まってはなりません (必ず、相対でなければなりません) が '/' で終わることは可能で、 また、禁止されるリソース名のサブストリングであってはなりません。 WebSphere Application Server は、無効な常時保護リソース名を無視します。

      このプロパティーが設定されると、ExtClassLoader リソース API の getResource(rscName) は、rscName に接頭部として常時保護リソース名が含まれる場合、 OSGi ゲートウェイに委任しません。

      例えば、リソース名 org/oss/pkg/ が常に保護されている場合、 ExtClassLoader.getResource(org/oss/pkgs/unexpected) は操作を OSGi ゲートウェイに委任せず、デプロイされた成果物が WebSphere Application Serverによって提供される org/oss/pkg/ パス内のリソースを事実上検出できないようにします。

      常時保護パッケージ内の .class ファイルの常時保護リソース名は、保護されているため指定不要です。

      デフォルト値は unsetです。

    4. デプロイされた成果物が、常に保護されているパッケージ内のサブパッケージまたはクラスに依存している場合は、JVM 汎用引数にシステム・プロパティー -Dcom.ibm.ws.classloader.server.alwaysAllowedPackages=<pkgOrClass1>,... ,<pkgOrClassN> を定義して、デプロイされた Java EE 成果物が OSS パッケージ <pkgOrClass1>...<pkgOrClassN> にアクセスできるようにします。 デプロイ済み成果物が、ある常時保護 OSS パッケージ内のあるインターフェースのみを必要とする場合に、この設定が高い可能性で使用されます。
      常時許可パッケージ: com.ibm.ws.classloader.server.alwaysAllowedPackages

      WebSphere Application Server がすべてのデプロイ済み成果物に対して可視にする、常時保護パッケージの ','区切りのサブパッケージまたは完全修飾クラス名。 WebSphere Application Server は、絶対名 ( '/'で始まる名前) を含め、常に保護されている無効なリソース名を無視します。 WebSphere Application Server は、無効な常時許可パッケージ名を無視します。

      例えば、パッケージ名 org.oss.pkg. が常に保護されており、 org.oss.pkg.api. が常に許可されている場合、 ExtClassLoader. loadClass (org.oss.pkg.api.PkgFactory) は OSGi Gateway に委任し、 WebSphere Application Serverによって提供される org.oss.pkg.api.PkgFactory とのリンクをデプロイ済みクラスに許可しますが、 WebSphere Application Serverによっても提供されるパッケージ org.oss.pkgor または org.oss.pkg.implのクラスへのリンクを防止します。

      デフォルト値は unsetです。

    5. デプロイされた成果物が常時保護リソース・パスのサブパスにリソースをロードする必要がある場合は、JVM 汎用引数にシステム・プロパティー -Dcom.ibm.ws.classloader.server.alwaysAllowedResources=<rsc1>...<rscN> を定義して、デプロイされた Java EE 成果物が OSS リソース <rsc1>...<rscN> にアクセスできるようにします。
      常時許可リソース: com.ibm.ws.classloader.server.alwaysAllowedResources

      WebSphere Application Server がデプロイされたすべての成果物に対して可視にする、常時保護リソース (パス) のサブパスまたは正確なパス名の ','区切りストリング。 WebSphere Application Server は、無効な常時許可リソース名を無視します。

      例えば、リソース名 org/oss/pkg/が常に保護されており、 "org/oss/pkg/api/ が常に許可されている場合、メソッド ExtClassLoader.getResource(org/oss/pkg/api/PkgFactory.class) は OSGi ゲートウェイに委任し、デプロイされたクラスが WebSphere Application Serverによって提供される "org/oss/pkg/api/PkgFactory.class"をディスカバーできるようにしますが、パス org/oss/pkg または org/oss/pkg/impl/( WebSphere Application Serverによっても提供される) でリソースをディスカバーできないようにします。

      デフォルト値は unsetです。

  5. 「適用」をクリックします。
  6. OK」をクリックします。
  7. 変更を保存します。 サーバーを再始動する前に、ファイル同期が完了していることを確認してください。
  8. WebSphere Application Server を再始動して、変更を有効にします。
  9. native_stdout.log を調べ、以前に定義されたシステム・プロパティーを探します。
    例えば、常時保護パッケージ org.apache.http. を指定した場合、 次のようなステートメントが含まれます。
    ProtectionMetaData.clinit: system property: com.ibm.ws.classloader.server.alwaysProtectedPackages=org.apache.http.
    	...
    	...
    	ProtectionMetaData.clinit: always-protected packages:
    		org.slf4j.
    		org.slf4j.spi.
    		org.slf4j.impl.
    		org.slf4j.helpers.
    		org.apache.http.

    前の例の org.apache.http. のように、常に保護されているパッケージのリストにパッケージが含まれている場合は、 WebSphere Application Serverで提供されている OSS パッケージを非表示にするようにサーバーが正しく構成されています。 サーバーが常時保護するパッケージは、org.slf4j など他にもあります。 ご使用のアプリケーションは、これらのパッケージからも保護されます。 必要な常時保護パッケージがリストに含まれていない場合は、 native_stdout.log の同じ作業域に、パッケージが無視された理由を示すメッセージがあります。 プロパティー値を修正して、サーバーを再始動してください。

  10. 新しいサーバー構成を実動にする前に、システム・プロパティー -Dws.ext.debug=true を削除します。