ヘッダーをスキップ
Oracle Containers for J2EE開発者ガイド
10g(10.1.3.1.0)
B31851-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

3 OC4Jクラス・ロード・フレームワークの利用

この章では、OC4Jの新しいクラス・ロード・フレームワークを理解して使用するためのガイドラインについて説明します。また、クラス・ローダーのよくある問題についての解説および問題を回避するための推奨事項も示します。

次の項目が含まれています。

OC4Jでのクラスのロード

この項には、次の内容が含まれています。

クラスのロードの概要

クラスのロードという用語は、特定のクラス名に対するバイトを探し、それをJavaクラスのインスタンスに変換する処理のことを示します。Java Virtual Machine(JVM)内のすべてのクラス・インスタンスは、バイトの配列として開始され、JVM仕様で定義されているクラス・ファイル形式で構成されています。

クラスのロードは、起動プロセスの間はJVMによって実行され、それ以降は、java.lang.ClassLoaderクラスのサブクラスであるクラス・ローダーが実行時にクラス・ファイルを検出してロードします。クラス・ローダーが提供する抽象化により、ローカルやリモートの記憶域だけでなく動的なクラスの生成について、クラス・バイトの検出先が不明でもJVMでクラスをロードできます。

クラス・ローダーは、1つ以上のコード・ソースを処理します。コード・ソースは、クラス・ローダーがクラスを検索するルートとなる場所です。コード・ソースは、バイナリ・クラス・ファイルの物理記憶域、最初にコンパイルする必要のあるJavaソースを示すように、または実行中に生成されるクラスを示すようにも定義できます。

標準のクラス・ローダーは、親子の階層として相互にリンクされており、各クラス・ローダーには親のクラス・ローダーが関連付けられています。この階層は、単純なチェーンや複数に枝分かれしたツリーなど、様々なツリーになります。

このような階層において、子のクラス・ローダーは、親のローダーからクラス・ローダーのセットをインポートします。OC4Jのコンテキストでは、OC4Jインスタンス内で実行するすべてのJ2EEアプリケーションは、systemアプリケーションの子です。結果として、アプリケーション・レベルで作成されるクラス・ローダーは、system.rootクラス・ローダーから一連のクラス・ローダーをインポートします。

OC4Jで使用されるクラス・ローダーのツリー構造のグラフィカルな表現については、下の図3-1を参照してください。

OC4Jにおける共有ライブラリでのクラスのバージョニング

クラス・ローダーの階層では、OC4JインスタンスにデプロイされたJ2EEアプリケーションは、デフォルトでdefaultアプリケーションから一連のライブラリを継承することが保証されます。このアプリケーションにバインドされたWebモジュールは、アプリケーションから一連のクラスを継承し、さらにOC4Jのアプリケーション階層のルートにあるsystemアプリケーションから継承されたクラスも継承します。

ただし、デフォルト以外のバージョンのライブラリやクラスがアプリケーションまたはモジュールで必要な場合は、このような継承モデルが望ましくない場合もあります。OC4Jのクラス・ロード・インフラストラクチャでは、この問題に対処するために、アプリケーションまたはモジュールに対して作成されたクラス・ローダーが、親クラス・ローダーがインポートしたデフォルトとは異なるバージョンの共有ライブラリをインポートしたり、継承したクラス・ローダーのセット全体から特定のクラス・ローダーを削除したりできるようになっています。

図3-1は、OC4Jにおけるクラス・ローダーのツリー構造を示しています。

図3-1 OC4Jのクラス・ローダー・ツリー

図3-1の説明が続きます
「図3-1 OC4Jのクラス・ローダー・ツリー」の説明

  • jre.bootstrapローダーは、JVMに組み込まれているネイティブ・ブートストラップ・ローダーに対するプロキシです。ネイティブ・ブートストラップ・ローダー自体が実行時に直接参照されることはありません。

  • jre.extensionローダーは、JREが提供する拡張ローダーのかわりとなるカスタム・ローダーです。

  • apiローダーには、すべてのアプリケーションおよびすべてのOC4J内部クラスから参照できる必要があるJ2EEクラスとOC4J APIクラスが含まれます。

  • oc4jローダーには、OC4Jのシステム・クラスが含まれます。

  • system.rootローダーは、OC4Jのsystemアプリケーション用に作成されます。

    systemはアプリケーション階層のルートにあるので、このローダーのクラスは、OC4Jインスタンスにデプロイされる他のすべてのアプリケーションにデフォルトで継承されます。

  • global.rootは、defaultアプリケーションに対して作成されるクラス・ローダーです。これは、OC4JインスタンスにデプロイされるすべてのJ2EEアプリケーションのデフォルトの親です。

  • app-name.rootは、デプロイされるアプリケーションに対するルート・ローダーです。

  • app-name.web.web-mod-nameクラス・ローダーは、それぞれがWARファイルにパッケージされているクラスであるWebモジュールを含みます。

  • app-name.jsp.jsp nameは、コンパイル済のJSP実装クラスをロードします。

OC4Jの共有クラス・ローダーであるoracle.jdbc:10.1.0_2oracle.jdbc:9.2.0_5oracle:xml:10_1_02およびxerces:xml:2.6.2は、OC4Jインスタンスで宣言されている共有ライブラリを表します。各共有ライブラリの定義は、次の項目で構成されます。

  • 共有ライブラリ名(xerces.xmlなど)

  • 通常は共有ライブラリの実装バージョンを表すバージョン番号(2.6.2など)

  • ライブラリを構成するクラスを含む1つ以上のコード・ソース(JARファイルまたはZIPファイル)

クラス・ローダーは、OC4Jインスタンス内の共有ライブラリ定義に基づいて実行時に作成されます。クラス・ローダーは、共有ライブラリ名とバージョン番号を連結したものを使用して登録されます(xerces.xml:2.6.2など)。

共有ライブラリの作成とインストールの方法の詳細は、「OC4Jでの共有ライブラリのインストールと公開」を参照してください。

デプロイされている3つのアプリケーションが、JDBCドライバ・クラスとXMLパーサー・クラスをロードする方法に注意してください。アプリケーション1は、デフォルトの動作に従って、共有ローダーoracle.jdbc:10_1_02oracle:xml:10_1_02に含まれるクラスを親から継承しています。一方、アプリケーション2とアプリケーション3は、それぞれが使用する代替ドライバ・クラス・ローダーと代替パーサー・クラス・ローダーをインポートしています。

デフォルトでは、アプリケーションは、systemアプリケーションから継承されたライブラリも含めて、親アプリケーションに存在する同じ一連の共有ライブラリを継承します。つまり、たとえば、アプリケーションはデフォルトでOracle JDBCドライバとOracle XMLパーサーを使用します。これはsystemアプリケーションから継承されるものです。

一方、OC4Jのクラス・バージョニング機能を使用すると、継承されるライブラリを別のバージョンでオーバーライドしたり、ともに継承されるライブラリのリストから、あるライブラリを削除したりできます。

アプリケーションがデフォルトでインポートする共有ライブラリ

OC4Jインスタンス内のすべてのアプリケーション・クラス・ローダーによってインポートされる共有ライブラリのデフォルトのセットは、ORACLE_HOME/j2ee/instance/system-application.xml<imported-shared-libraries>要素で指定されています。これはsystemアプリケーション用の構成ファイルで、アプリケーション階層のルートにあるOracle Containers for J2EEの内部コンポーネントであり、クラスとOC4Jの起動に必要な構成を提供します。

デフォルトでは、OC4Jインスタンスにデプロイされたアプリケーションは、これらのOracle共有ライブラリを継承します。

  • oracle.jdbc:10.1.0_2

  • oracle.xml:10.1.0_2

  • oracle.cache:10.1.3

  • oracle.http.client:10.1.3

  • oracle.sqlj:10.1.3

  • soap:10.1.3

  • oracle.jwsdl:10.1.3

デフォルト以外のバージョンの共有ライブラリをインポートするためのアプリケーションの構成

system-application.xmlで宣言されている共有ライブラリと同じ名前の共有ライブラリを作成し、異なるバージョン番号を割り当てることで、system-application.xmlで宣言されているものとは異なるバージョンの共有ライブラリをアプリケーションで強制的にインポートできます。その場合、この共有ライブラリをインポートするようにアプリケーションを構成します。

詳細は次の項を参照してください。

例: 旧バージョンのOracle JDBCドライバのインポート

次の例では、OC4J 10g(10.1.3.1.0)にパッケージされているバージョンよりも前のバージョンのOracle JDBCドライバであるOracle 9.2.0_5 JDBCドライバを使用するように、アプリケーションを構成する方法を示します。この例は、このシンJDBCドライバのみに適用され、Oracle Call Interface(OCI)ドライバには適用されません。

手順1: OC4Jで共有ライブラリを作成する

「共有ライブラリをインストールおよび公開するためのオプション」で説明されているいずれかのメカニズムを使用して、9.2.x JDBCドライバ用の共有ライブラリをインストールできます。この例では、Application Server Controlコンソールを使用してこのタスクを実行します。


注意:

OC4JにパッケージされていないJDBCドライバを使用するには、アプリケーションで特に使用するためのマネージド・データソースを作成した後、それを使用するようにアプリケーションを構成する必要があります。

アプリケーションで使用するデフォルトのJDBCドライバとデータソースはグローバルsystemアプリケーションのクラス・ローダーによってインポートされるため、このような作業が必要です。アプリケーションは別のドライバをロードするため、そのドライバが使用するデータソースもロードする必要があります。

アプリケーション固有のマネージド・データソースを作成して使用する方法の詳細は、『Oracle Containers for J2EEサービス・ガイド』を参照してください。


  1. 「管理」「共有ライブラリ」の順にクリックします。デフォルトのJDBCドライバ共有ライブラリoracle.jdbc:10.1.0_2を確認します。

  2. 「作成」をクリックします。

  3. 共有ライブラリの名前を入力します。この場合は、既存のライブラリと同じ名前のoracle.jdbcを入力します。

  4. 共有ライブラリのバージョンとして、この場合は9.2.0_5と入力します。

  5. 「追加」をクリックして、ライブラリのJARファイルをOC4Jインスタンスにアップロードします。次の共有ライブラリ宣言がORACLE_HOME/j2ee/instance/server.xmlファイルに追加されます。

    <shared-library name="oracle.jdbc" version="9.2.0_5">
                    <code-source path="ojdbc14.jar"/>
            </shared-library>
    

手順2: 共有ライブラリを使用するようにアプリケーションを構成する

共有ライブラリをOC4Jに作成すると、OC4Jとともにインストールされるデフォルトの共有ライブラリのかわりにそれを使用するように、アプリケーションを構成できます。

次の例では、アプリケーションのデプロイ時に、Application Server Controlコンソールを使用してこれを行う方法を示します。

  1. 「アプリケーション」→「デプロイ」をクリックして、Application Server Controlコンソールのデプロイ・ウィザードを起動します。

  2. ウィザードの最初のページで、アプリケーションへのパスを指定します。

  3. 2番目のページでは、アプリケーションの名前とコンテキストURIマッピングを指定します。

  4. ウィザードの3ページ目(「デプロイ: デプロイ設定」)では、「クラスのロードの構成」をクリックします。

  5. oracle.jdbc共有ライブラリの両方のバージョンが「共有ライブラリのインポート」フレームに表示されることを確認します。「使用する最高バージョン」列で、使用するバージョン番号(9.2.0_5)を指定します。

  6. アプリケーションをデプロイします。アプリケーションをデプロイしたら、アプリケーションのorion-application.xmlファイルに次のエントリがあることを確認します。

    <imported-shared-libraries>
      <import-shared-library name="oracle.jdbc" max-version="9.2.0_05"/>
    </imported-shared-libraries>
    

例: DataDirect JDBCドライバを使用するアプリケーションの構成

Oracle Application Serverディストリビューションには、Oracle以外のデータベースに接続するためのJDBCドライバがいくつか含まれています。次の例では、DataDirect Sybaseドライバを使用してSybaseデータベースに接続するようにアプリケーションを構成する方法を示します。

手順1: OC4Jで共有ライブラリを作成する

「共有ライブラリをインストールおよび公開するためのオプション」で説明されているいずれかのメカニズムを使用して、ドライバ用の共有ライブラリをインストールできます。この例では、Application Server Controlコンソールを使用して行います。

  1. 「管理」「共有ライブラリ」の順にクリックします。

  2. 「作成」をクリックします。

  3. 共有ライブラリの名前(たとえばsybase.jdbc)を入力します。

  4. 共有ライブラリのバージョン(たとえば1.0)を入力します。

  5. 「追加」をクリックして、ライブラリのJARファイルをOC4Jインスタンスにアップロードします。Oracle Application Serverで提供されているいずれかのDataDirectドライバを使用するには、YMbase.jarファイルとYMutil.jarファイルが必要であることに注意してください。

    • YMsybase.jar

    • YMbase.jar

    • YMutil.jar

    次の共有ライブラリ宣言がORACLE_HOME/j2ee/instance/server.xmlファイルに追加されます。

    <shared-library name="sybase.jdbc" version="1.0">
                    <code-source path="YMbase.jar"/>
                    <code-source path="YMutil.jar"/>
                    <code-source path="YMsybase.jar"/>
            </shared-library>
    

手順2: 共有ライブラリを使用するようにアプリケーションを構成する

共有ライブラリをOC4Jに作成すると、OC4Jとともにインストールされるデフォルトの共有ライブラリのかわりにそれを使用するように、アプリケーションを構成できます。

次の例では、アプリケーションのデプロイ時に、Application Server Controlコンソールを使用してこれを行う方法を示します。

  1. 「アプリケーション」→「デプロイ」をクリックして、Application Server Controlコンソールのデプロイ・ウィザードを起動します。

  2. ウィザードの最初のページで、アプリケーションへのパスを指定します。

  3. 2番目のページでは、アプリケーションの名前とコンテキストURIマッピングを指定します。

  4. ウィザードの3ページ目(「デプロイ: デプロイ設定」)では、「クラスのロードの構成」をクリックします。

  5. sybase.jdbc共有ライブラリの「インポート」チェック・ボックスを選択します。必要であれば、使用する最高バージョンとして1.0を指定します。

  6. アプリケーションをデプロイします。アプリケーションをデプロイしたら、アプリケーションのorion-application.xmlファイルに次のエントリがあることを確認します。

    <imported-shared-libraries>
      <import-shared-library name="sybase.jdbc" max-version="1.0"/>
    </imported-shared-libraries>
    

デフォルトでインポートされるOracle共有ライブラリの削除または置換

共有ライブラリ・フレームワークでは、アプリケーションが親から継承した共有ライブラリのセットから、特定の共有ライブラリを削除できます。また、必要に応じて、かわりに別の共有ライブラリをインポートすることもできます。

デフォルトで継承した共有ライブラリは、アプリケーションのorion-application.xmlファイルの<imported-shared-libraries><remove-inherited>サブ要素を使用して削除できます。削除するライブラリの名前は、name属性の値として指定します。

たとえば、orion-application.xmlで次のエントリを指定すると、Oracle TopLink共有ライブラリがアプリケーションにインポートされません。

<orion-application>
  <imported-shared-libraries>
    <remove-inherited name="oracle.toplink"/>
  </imported-shared-libraries>
</orion-application>

詳細な例については次の項を参照してください。

例: XercesパーサーでのOracle XMLパーサーの置換え

次の例では、Application Server Controlコンソールを使用して、systemアプリケーションから継承されたデフォルトの共有ライブラリ・セットからOracle XMLパーサーを削除する方法を示します。また、アプリケーションがそのかわりにXerces XMLパーサーを使用するように設定します。

手順1: OC4Jで共有ライブラリを作成する

「共有ライブラリをインストールおよび公開するためのオプション」で説明されているいずれかのメカニズムを使用して、Xercesパーサー用の共有ライブラリをインストールできます。この例では、Application Server Controlコンソールを使用して行います。

  1. 「管理」「共有ライブラリ」の順にクリックします。

  2. 「作成」をクリックします。

  3. 共有ライブラリの名前を入力します。この例では、xerces.xmlと入力します。

  4. 共有ライブラリのバージョンとして、この場合は2.5.0と入力します。

  5. 「追加」をクリックして、ライブラリのJARファイルをOC4Jインスタンスにアップロードします。次のApacheライブラリをアップロードします。

    • xercesImpl.jar

    • xml-apis.jar

    次の共有ライブラリ宣言がORACLE_HOME/j2ee/instance/server.xmlファイルに追加されます。

    <shared-library name="xerces.mxl" version="2.5.0">
                    <code-source path="xercesImpl.jar"/>
      <code-source path="xml-apis.jar"/>
            </shared-library>
    

手順2: 共有ライブラリを使用するようにアプリケーションを構成する

共有ライブラリをOC4Jに作成すると、OC4JとともにインストールされるデフォルトのパーサーのかわりにXercesパーサーを使用するように、アプリケーションを構成できます。

次の例では、アプリケーションのデプロイ時に、Application Server Controlコンソールを使用してこれを行う方法を示します。

  1. 「アプリケーション」「デプロイ」をクリックして、Application Server Controlコンソールのデプロイ・ウィザードを起動します。

  2. ウィザードの最初のページで、アプリケーションへのパスを指定します。

  3. 2番目のページでは、アプリケーションの名前とコンテキストURIマッピングを指定します。

  4. ウィザードの3ページ目(「デプロイ: デプロイ設定」)では、「クラスのロードの構成」をクリックします。

  5. xerces.xml共有ライブラリの「インポート」チェック・ボックスを選択します。必要であれば、使用する最高バージョンとして2.5.0を指定します。

  6. Oracleパーサーを明示的に削除するには、oracle.xml共有ライブラリに対する「インポート」チェック・ボックスの選択を解除して、アプリケーションが継承する共有ライブラリのリストから削除します。

  7. 必要であれば、「デプロイ・プランの保存」ボタンをクリックして、再利用できるようにプランを保存します。

  8. アプリケーションをデプロイします。アプリケーションをデプロイしたら、アプリケーションのorion-application.xmlファイルに次のエントリがあることを確認します。

    <orion-application>
      <imported-shared-libraries>
        <remove-inherited name="oracle.xml"/>
        <import-shared-library name="xerces.xml" max-version="2.5.0/>
      </imported-shared-libraries>
    </orion-application>
    

例: デプロイ時のOracle共有ライブラリの削除

次の例では、Application Server Controlコンソールを使用して、アプリケーションのデプロイ時に、Oracle TopLink共有ライブラリを削除する方法を示します。

  1. 「アプリケーション」「デプロイ」をクリックして、Application Server Controlコンソールのデプロイ・ウィザードを起動します。

  2. ウィザードの最初のページで、アプリケーションへのパスを指定します。

  3. 2番目のページでは、アプリケーションの名前とコンテキストURIマッピングを指定します。

  4. ウィザードの3ページ目(「デプロイ: デプロイ設定」)では、「クラスのロードの構成」をクリックします。

  5. oracle.toplink共有ライブラリに対する「インポート」チェック・ボックスの選択を解除して、アプリケーションが継承する共有ライブラリのリストから削除します。

  6. 必要であれば、「デプロイ・プランの保存」ボタンをクリックして、再利用できるようにプランを保存します。

  7. アプリケーションをデプロイします。アプリケーションをデプロイしたら、アプリケーションのorion-application.xmlファイルに次のエントリがあることを確認します。

    <orion-application>
      <imported-shared-libraries>
        <remove-inherited name="oracle.toplink"/>
      </imported-shared-libraries>
    </orion-application>
    

Oracle共有ライブラリの代替としてのパッケージ化されたJARの使用

クラス・ロード・インフラストラクチャでは、XMLパーサーまたはJDBCドライバをJARとしてアプリケーションにパッケージし、OC4JでインストールされるOracle XMLパーサーまたはJDBCドライバのかわりにそれを使用するように設定できます。JARをOC4J内の共有ライブラリとして宣言する必要はありません。

独自の共有ライブラリを使用するためのアプリケーションの構成

この場合、デフォルトで継承されるOracleライブラリをorion-application.xml<remove-inherited>タグに指定します。orion-application.xmlは、JARとともにアプリケーションのEARファイルにパッケージされます。OC4Jにデプロイされた後、アプリケーションはOC4Jでインストールされるデフォルトのライブラリをインポートせず、かわりにアプリケーションのクラス・ローダーがパッケージされたライブラリを検出してロードします。

orion-application.xmlで次のように記述すると、アプリケーションのクラス・ローダーはOracle XMLパーサーをインポートしません。

<imported-shared-libraries>
  <remove-inherited name="oracle.xml"/>
</imported-shared-libraries>

Webアプリケーションの場合は、アプリケーションのorion-web.xmlディスクリプタ・ファイルでの記述を通して、アプリケーションのWARファイルにバンドルされているクラスを使用するように指定できます。

まず、このファイルに<web-app-class-loader>要素を追加するか、またはこの要素のコメントを外します。次に、この要素のsearch-local-classes-first属性をtrueに設定すると、クラス・ローダーはWARにパッケージされているライブラリを検索してロードし、OC4Jでパッケージされている対応するライブラリではなく、このライブラリを使用します。

Application Server Controlコンソールを使用してデプロイ時にこれを行う方法の詳細は、後述する「デプロイ時のsearch-local-classes-firstの指定」を参照してください。

orion-web.xmlのエントリは次のようになります。

<orion-web-app ...>
  ...
  <web-app-class-loader search-local-classes-first="true"
   include-war-manifest-class-path="true" />
  ...
</orion-web-app>

この方法は保証されたソリューションではないことに注意してください。階層のさらに上位のアプリケーションが同じクラスを含む共有ライブラリをインポートした場合は、衝突が発生する可能性があります。このような衝突はデバッグすることが困難です。可能なかぎり、この章で解説されている共有ライブラリ・メカニズムを使用し、Webアプリケーションが正しいライブラリを使用するようにする必要があります。

デプロイ時のsearch-local-classes-firstの指定

次の例では、デプロイ時にWebモジュールに対して生成されるorion-web.xmlファイルでsearch-local-classes-first属性を、Application Server Controlコンソールを使用して設定する方法を示します。

  1. 「アプリケーション」「デプロイ」をクリックして、Application Server Controlコンソールのデプロイ・ウィザードを起動します。

  2. ウィザードの最初のページで、アプリケーションへのパスを指定します。

  3. 2番目のページでは、アプリケーションの名前とコンテキストURIマッピングを指定します。

  4. ウィザードの3ページ目(「デプロイ: デプロイ設定」)では、「クラスのロードの構成」をクリックします。

  5. 「Webモジュールのクラス・ローダーの構成」で、使用するローカルJARファイルを含むWebモジュールの名前の隣の「最初にローカル・クラスを検索」チェック・ボックスを選択します。

  6. 必要であれば、「デプロイ・プランの保存」ボタンをクリックして、再利用できるようにプランを保存します。

OC4Jでの共有ライブラリのインストールと公開

OC4Jインスタンスでの共有ライブラリの作成は、基本的に2つの手順から成る処理です。最初に、共有ライブラリを構成するバイナリを、OC4J内の適切なディレクトリにインストールする必要があります。その後、OC4Jサーバー構成ファイル(server.xml)で共有ライブラリを宣言する必要があり、共有ライブラリは原則的にOC4Jインスタンス内に公開されます。

この項には、次の内容が含まれています。

共有ライブラリを使用する必要がある場合

通常、OC4Jにデプロイされるアプリケーションは、OC4Jにパッケージされた共有ライブラリのセットを使用します。これは、systemアプリケーションから継承されます。ただし、アプリケーションの親から継承したライブラリの置換または削除が必要になる場合があります。たとえば次のような場合です。

  • OC4Jにパッケージされているバージョンとは異なるバージョンのOracle JDBCドライバを使用する場合

  • OC4JにパッケージされているOracle XMLパーサーをアプリケーションで使用する別のパーサーに置き換える場合

  • すべてのアプリケーションではなく、1つまたは複数の特定のアプリケーションで固有のクラスを共有する場合

  • StrutsやSpring Frameworkなどのオープン・ソース・ライブラリを、複数のWebアプリケーションで利用できるようにする場合

共有ライブラリのインストールと公開のオプション

OC4Jでは、1つまたは複数のOC4Jインスタンスに共有ライブラリをインストールして公開するためのオプションがいくつか用意されています。これらのメカニズムはいずれも、共有ライブラリをORACLE_HOME/j2ee/instance/shared-libディレクトリにインストールし、server.xmlに必要なエントリを作成します。

  • Oracle Enterprise Manager 10g Application Server Controlコンソール

    「管理」「管理タスク」「共有ライブラリ」から、特定のOC4Jインスタンスに共有ライブラリをインストールできます。

  • publishSharedLibrary Antタスク

    スタンドアロンOC4Jサーバー、またはOracle Process Manager and Notification Server(OPMN)によって管理されているOracle Application Server環境の単一のOC4Jインスタンスに共有ライブラリをインストールできます。

  • admin_client.jar-publishSharedLibraryコマンド

    この方法でも、OPMNで管理される単一のOC4JインスタンスまたはスタンドアロンOC4Jサーバーに共有ライブラリをインストールできます。

また、次の「OC4Jインスタンス内で共有ライブラリをインストールして公開する方法」で解説されている手順に従って、手動でOC4Jインスタンス内に共有ライブラリをインストールして公開することもできます。


注意:

JDK 1.4を使用している場合は、Oracle Application Server 10.1.3は共有ライブラリとしてJDKに搭載されているXalanライブラリの使用をサポートしません。Xalanライブラリを使用するには、次の2つの選択肢があります。
  • 埋込みXalanライブラリが共有ライブラリとしてサポートされているJDK 1.5(JDK 5)を使用

  • JDK 1.4では、Xalanライブラリの埋込みバージョンではなく、スタンドアロン・ディストリビューションを使用


OC4Jインスタンス内で共有ライブラリをインストールして公開する方法

共有ライブラリは、OC4JのORACLE_HOME/j2ee/instance/shared-libディレクトリにインストールされます。この処理では、このディレクトリ内に正しいディレクトリ構造が作成された後、ライブラリを構成するJARまたはZIPファイルがそこにコピーされます。

OC4Jでは、この処理を自動化するツールがいくつか提供されています。概要については、「共有ライブラリのインストールと公開のオプション」を参照してください。

まず、ライブラリ用の次のようなディレクトリ構造が、このディレクトリの中に作成されます。

ORACLE_HOME/j2ee/instance/shared-lib
  /library_name
    /version
      filename.jar
      filename.zip
      ...

ディレクトリ構造内の変数には次の値があります。

  • instanceはOC4Jインスタンスの名前で、Oracle Application Server環境ではデフォルトでhome、スタンドアロンOC4Jサーバーでは常にhomeです。

  • library_nameは、共有ライブラリの名前が付けられたディレクトリです(acme.commonなど)。

    共通のAPIが複数のベンダーによって実装される場合は、ベンダー名とテクノロジの名称がディレクトリの名前に含まれている必要があります(たとえば、oracle.jdbcxerces.xml)。テクノロジが単独のベンダーによって実装される場合は、テクノロジの名称のみで十分です。

  • versionは、共有ライブラリのバージョン番号を名前とするサブディレクトリです(たとえば2.5)。可能であれば、この値はコードの実装バージョンを反映している必要があります。

これらのディレクトリを作成したら、共有ライブラリを構成するクラスを含むJARファイルまたはZIPファイルを、versionサブディレクトリにコピーします。たとえば、サンプルのライブラリがacme-apis.jaracmeImpl.jarで構成されているものとします。

前述の例を使用すると、OC4Jサーバー内に作成されるディレクトリ構造は次のようになります。

ORACLE_HOME/j2ee/instance/shared-lib
  /acme.common
    /2.5
      acme-apis.jar
      acmeImpl.jar

次の例に示すように、このディレクトリ構造内に各バージョンのアーカイブ・ファイル用に新しいサブディレクトリを作成することで、共有ライブラリの複数のバージョンがインストールされます。

ORACLE_HOME/j2ee/instance/shared-lib
  /acme.common
    /2.5
      acme-apis.jar
      acmeImpl.jar
    /3.0
      acme-apis.jar
      acmeImpl.jar

コード・ソースがインストールされると、ORACLE_HOME/j2ee/instance/server.xmlファイルに追加される<shared-library>要素内で共有ライブラリが定義されます。このファイルには、OC4Jインスタンスの構成データが含まれます。<shared-library>要素には次の属性とサブ要素が含まれます。

  • 必須のname属性。この属性の値は、/shared-libディレクトリ内に作成されている共有ライブラリ・ディレクトリの名前と一致する必要があります。

  • 必須のversion属性。この属性の値は、/shared-lib/library_nameディレクトリ内にある共有ライブラリのアーカイブ・ファイルを含むサブディレクトリの名前として使用されているバージョン番号と一致する必要があります。

  • 1つ以上の<code-source>サブ要素。それぞれがライブラリに属するJARファイルまたはZIPファイルへのパスを定義するpath属性を含みます。

    /shared-libディレクトリの外部の場合は、パスは絶対指定にします。それ以外の場合は、/shared-lib/library_nameディレクトリ内のJARファイルまたはZIPファイルを含むサブディレクトリに対する相対パスを指定できます。相対指定の場合は、pathの値としてアーカイブ・ファイル名のみを指定する必要があります。

次に、前述の例の共有ライブラリに対するserver.xml構成ファイルでの共有ライブラリ定義の例を示します。コード・ソースのパスは、/shared-lib/acme.commonディレクトリ内のJARまたはZIPファイルを含むサブディレクトリに対する相対指定です。したがって、アーカイブ・ファイル名のみがpathの値として指定されています。

<shared-library name="acme.common" version="2.5">
  <code-source path="acme-apis.jar">
  <code-source path="acmeImpl.jar"/>
</shared-library>

必要であれば、path="*"と設定することで、サブディレクトリ内のすべてのアーカイブを使用するようにOC4Jに強制することができます。次に例を示します。

<shared-library name="acme.common" version="2.5">
  <code-source path="*" />
</shared-library>

さらに、1つ以上の他の共有ライブラリをインポートするように、共有ライブラリを構成できます。<shared-library>要素では、オプションとして1つ以上の<import-shared-library>要素を指定できます。この要素では、構成している共有ライブラリがインポートする共有ライブラリを指定します。インポート対象の共有ライブラリも、OC4Jホスト上にインストールされ、公開されている必要があります。

次のサンプル・コードでは、acme.common共有ライブラリがxyz.log共有ライブラリをインポートします。

<shared-library name="acme.common" version="2.5">
  <import-shared-library name="xyz.log"/>
  <code-source path="acme-apis.jar"/>
  <code-source path="acmeImpl.jar"/>
</shared-library>

実行時に相対指定されたコード・ソースのパスが検出されると、共有ライブラリ・ディレクトリ(/shared-lib)、共有ライブラリ名およびバージョン番号が連結されて絶対パスが作成されます。たとえば、前述のサンプル・エントリは、これらのパスに対し次のように解決されます。

ORACLE_HOME/j2ee/instance/shared-lib/acme.common/2.5/acme-apis.jar
ORACLE_HOME/j2ee/instance/shared-lib/acme.common/2.5/acmeImpl.jar

共有ライブラリをインポートするためのアプリケーションの構成

共有ライブラリをインストールすると、次のいずれかのオプションを使用して、共有ライブラリをインポートするようにアプリケーションを構成できます。


注意:

ここで示したいずれかのオプションを使用して依存性を宣言すると、その共有ライブラリはアプリケーションにとって必須になります。共有ライブラリがまだインストールされておらず、OC4Jインスタンス内で公開されていないと、エラーが発生します。

アプリケーションのOC4Jデプロイメント・ディスクリプタでの依存性の宣言

依存性は、依存するアプリケーションのorion-application.xmlデプロイメント・ディスクリプタに記述を追加することで宣言できます。

依存性を宣言するには、アプリケーション固有のorion-application.xml構成ファイルに<imported-shared-libraries>要素を追加します。この要素は1つ以上の<import-shared-library>サブ要素を取り、それぞれでインポートする共有ライブラリを指定します。

<import-shared-library>要素には次の属性があります。

  • name: 共有ライブラリの名前です。

  • min-versionおよびmax-version: 省略可能な属性で、ライブラリの最低バージョンと最高バージョンを指定できます。インストールされている最新のバージョンのライブラリを使用する場合は、バージョン番号を指定しません。

orion-application.xmlの次のエントリによって、アプリケーションで使用するacme.common:2.5共有ライブラリがインポートされます。

<imported-shared-libraries>
  <import-shared-library name="acme.common" max-version="2.6"/>
</imported-shared-libraries>

アプリケーションのマニフェスト・ファイルでの依存性の宣言

オプション・パッケージとも呼ばれるJavaの標準拡張メカニズムを利用すると、共有ライブラリ内のJARまたはZIPファイルに対するアプリケーションの依存性を宣言できます。これは、インストールされているライブラリに対する依存性を宣言するための、J2EEの標準的なメカニズムです。

このメカニズムを使用するには、そのMANIFEST.MFファイルの中で、依存するJARまたはZIPファイルを名前付き拡張として宣言する必要があります。この名前はExtension-Name属性の値として指定します。たとえば、次に示すマニフェストのエントリでは、拡張としてacme.commonが定義されています。

Extension-Name: acme.common
Specification-Vendor: Acme, Inc
Specification-Version: 2.5
Implementation-Vendor-Id: com.acme
Implementation-Vendor: Acme, Inc
Implementation-Version: 2.5

次に、マニフェスト・ファイルの中で、共有ライブラリに依存するアプリケーションの依存性を宣言します。次に示すマニフェストの属性によって、アプリケーションはacme.common:2.5共有ライブラリをインポートします。name-Extension-Nameの値が、JARまたはZIPファイルのマニフェストで指定されているExtension-Nameの値と正確に一致することに注意してください。

Extension-List: acme
acme-Extension-Name: acme.common
acme-Implementation-Version: 2.5

マニフェスト・ファイルを使用して依存性を宣言する方法の詳細は、次のWebサイトを参照してください。

http://java.sun.com/j2se/1.4.2/docs/guide/extensions/versioning.html

すべてのデプロイ済アプリケーションで特定の共有ライブラリをインポートするための構成

OC4Jインスタンスにデプロイされているすべてのアプリケーションで、確実に同じバージョンの共有ライブラリを使用するには、その共有ライブラリをインポートするようにデフォルト・アプリケーションを構成します。defaultはOC4Jにデプロイされているすべてのアプリケーションの親であるため、defaultがインポートする共有ライブラリもこれらのアプリケーションにインポートされます。

構成を管理するには、「アプリケーションのOC4Jデプロイメント・ディスクリプタでの依存性の宣言」で示されているXMLの記述を、defaultアプリケーションの構成ファイルであるORACLE_HOME/j2ee/instance/application.xmlファイルに追加します。

application.xmlの次のエントリによって、デプロイされているすべてのアプリケーションで、確実にacme.common共有ライブラリのバージョン2.0が使用されます。

<imported-shared-libraries>
  <import-shared-library name="acme.common" max-version="2.0"/>
</imported-shared-libraries>

アプリケーションに独自のバージョンの共有ライブラリが含まれていたとしても、アプリケーションはdefaultアプリケーションからインポートされるバージョンの共有ライブラリを使用することに注意してください。それが望ましくない場合は、「デフォルトでインポートされるOracle共有ライブラリの削除または置換」で説明されている処理を使用して、defaultからインポートされるバージョンを削除できます。

applibディレクトリを使用するライブラリの共有

OC4J内のアプリケーション間でライブラリを共有するレガシー・メカニズムでは、共有されるJARまたZIPファイルはORACLE_HOME/j2ee/instance/applibディレクトリにインストールされますが、このメカニズムは現在のリリースのOC4Jでもまだサポートされています。このディレクトリ内のすべてのJARおよびZIPファイルは、global.libraries共有ライブラリに組み込まれて、OC4Jインスタンスのすべてのアプリケーションで利用できるようになります。

このレガシー機能のサポートは、今後のOC4Jのリリースで削除されます。できるだけこの章で説明されている新しい共有ライブラリ・メカニズムを使用することを、強くお薦めします。

application.xml内のライブラリ・ディレクトリの指定

application.xmlファイルの<library-directory>要素は、このOC4Jインスタンスに対してライブラリ・パスとして追加する、ディレクトリ、JARアーカイブまたはZIPアーカイブに対する、相対パス、絶対パスまたはURLを指定します。OC4Jの起動時に、アーカイブを含めるためにディレクトリがスキャンされます。

アプリケーション用のapplication.xmファイルがversion="5"属性セット(JavaEE 5アプリケーション)を持っている場合、.earファイルのデプロイメント・ディスクリプタの<library-directory>要素は、アプリケーション・コンポーネントでライブラリを共有できるようにするためのライブラリ・ディレクトリの名前を含むことができます。

<application version="5">
    <library-directory>app2lib</library-directory>
    <module>
        <ejb>ejb.jar</ejb>
    </module></application>

<library-directory>要素が指定されていない場合、または.earファイルがデプロイメント・ディスクリプタを含まない場合、libというディレクトリが使用されます。

ライブラリ・ディレクトリがないことを指定するために、空の<library-directory>要素を使用することができます。次に例を示します。

<application version="5">
    <library-directory></library-directory>
    <module>
        <ejb>ejb.jar</ejb>
    </module></application>

<library-directory>要素は、JavaEE 5仕様で定義されているクラスパスの依存性を定義するための標準のメカニズムを提供します。OC4J 10g(10.1.3.1.0)では、ライブラリ・ディレクトリ内にある.jar拡張子の付いたすべてのファイル(サブディレクトリ内は除く)は、アプリケーション・クライアントを除くEARファイルに含まれたすべてのコンポーネントに対して使用できます。これらのJARファイル内にあるライブラリは、アプリケーションにバンドルされているか個別にインストールされたかにかかわらず、他のライブラリを参照することができます。

また、OC4J 10g(10.1.3.1.0)は、J2EE 1.4アプリケーション内の<library-directory>要素をサポートしますが、次の注意事項があります。

orion-application.xmlファイルにある固有の<library>要素は、<library-directory>と同じ機能を提供します。

<library-directory>要素を使用するアプリケーションまたは空の<library-directory>要素を使用しないJavaEE 5アプリケーションは、ライブラリ・ディレクトリ内でファイルを反復してこれらをクラスパスへ追加する、追加のデプロイ・ステップを持ちます。

クラス・ロードのベスト・プラクティス

この項では、クラスのロードに関する問題を回避するためのガイドラインについて説明します。

クラスの依存性を宣言する

アプリケーションのMANIFEST.MFファイルまたはorion-application.xmlファイルで、依存性を明示的に宣言します。参照されていない依存性または不明な依存性は、アプリケーションを別の環境に移動する際に放置されます。

依存性をグループ化する

すべての依存性が同じレベルまたはそれより上位のレベルで参照されるようにします。ライブラリを移動する必要がある場合は、すべての依存性が引き続き参照されていることを確認します。アプリケーション・リソース、依存するサード・パーティ製ライブラリおよび他のエンタープライズ・モジュールが、自己完結方式でパッケージされていることを確認します。

ライブラリを複製するのではなく共有する

ライブラリの複製は行わないようにします。複製すると、ディスクとメモリーの使用量が増え、バージョンの問題が発生する可能性があります。

ライブラリの可視性を最小限にする

依存ライブラリは、すべての依存性を満たす最も低い可視性レベルに置く必要があります。

構成の移植性を維持する

構成オプションを次の順序で選択します。

  1. 標準J2EEオプション

  2. EARファイル内で表すことのできるオプション

  3. サーバー・レベルのオプション

  4. J2SE拡張オプション

正しいクラス・ローダーを確実に使用する

Class.forName()を呼び出すことでリフレクションを使用する場合は、Thread.currentThread().getContextClassLoaderによって返されるクラス・ローダーを常に明示的に渡します。プロパティ・ファイルをロードする場合、次を使用します。

Thread.currentThread().getContextClassLoader().getResourceAsStream()

OC4Jでのクラス・ロード関連の問題のトラブルシューティング

OC4Jでは、クラスのロードに関する問題のトラブルシューティングに役立つ機能が提供されています。

トラブルシューティングの概要

Javaでのクラス・ロード・エラーのほとんどは可視性に関するもので、原因は可視性の不足か、またはごくまれに可視性の過剰です。この場合の可視性とは、クラスパスで利用可能なクラスとリソースのセットのことです。クラスパスとは、一連のローダーとそれに含まれるコード・ソース(JARファイル、ZIPファイルおよびディレクトリなど)に対する検索パスです。

JavaSEでのクラスパスは、通常、コマンドラインまたはメインJARのマニフェスト・ファイルで指定されているコード・ソースのリストと考えられています。これらのコード・ソースはすべて、一般にシステム・ローダーと呼ばれる単一のローダーでデプロイされます。このローダーは、JRE拡張ローダー(通常は、jre/lib/extディレクトリ内のJARファイル用)およびJREブートストラップ・ローダー(rt.jarなどを含む)という2つのローダーに結び付けられています。

1つのクラスパスが存在するという考え方は、誤解を招くことがよくあります。クラスの参照のたびに、検索は特定のローダーから開始して、(通常は)そのクラスより上のローダーのみを参照できます。つまり、拡張ローダーから開始する検索のクラスパスは、システム・ローダーから開始する場合のクラスパスと大きく異なることになります。

JavaEEでは、単一のシステム・ローダーのかわりに複数のクラス・ローダーが必要であるため、状況はさらに複雑になります。デプロイされた各アプリケーションには、他のすべてのアプリケーションとは異なるローダーが少なくとも1つあるため、アプリケーションごとに個別のクラスパスが存在します。各Webモジュールは異なるローダーでデプロイされるため、たとえ単一のアプリケーションの中でも、異なるクラスパスが存在することがよくあります。

このことは、異なるモジュールの中から次の呼出しを行うことで簡単にわかります。OC4Jは、呼び出したモジュールに対して正しいクラスパスを返します。

System.getProperty("java.class.path");

アプリケーションに対するクラスの可視性に影響を与える構成オプションがいくつもあります。表3-1は、OC4Jの最も一般的なオプションの一覧です。JavaEE環境において可能性のあるローダーとコード・ソースの組合せを考えると、可視性エラーがどのように発生するのかが簡単にわかります。多くの場合で、問題を除去するために必要なことは簡単な構成の変更のみですが、変更する内容を理解することが面倒な場合があります。

表3-1 クラスの可視性に影響を与える構成オプション

クラス・ローダー 構成オプション

構成される共有ライブラリ

server.xml<code-source>


server.xml<import-shared-library>

app-name.root

orion-application.xml<import-shared-library>


orion-application.xml<library>のJARファイル、ZIPファイルおよびディレクトリ


application.xml<library-directory>のJARファイル、ZIPファイルおよびディレクトリ


orion-application.xml<ejb>のJARファイルおよびZIPファイル


RARファイル: ルートにあるすべてのJARファイルおよびZIPファイル


RARファイル: <native-library>ディレクトリ・パス


JARファイルおよびZIPファイルの上位のマニフェスト・クラスパス

app-name.web.web-mod-name

WARファイル: マニフェスト・クラスパス


WARファイル: WEB-INF/クラス


WARファイル: WEB-INF/lib/のすべてのJARファイルおよびZIPファイル


orion-web.xmlの<classpath>のすべてのJARファイル、ZIPファイルおよびディレクトリ


JARファイルの上位のマニフェスト・クラスパス


orion-web.xmlsearch-local-classes-first属性


共有ライブラリはアプリケーション・ルートから継承


クラス・ローダーのエラーと例外

J2EEにおけるほとんどのクラス・ロード・エラーは、普通、小さな例外セットの1つとして表面化します。OC4Jクラス・ロード・インフラストラクチャは、次の標準クラス・ロード構成の例外それぞれに対して、注釈付きサブクラスを提供します。

これらのサブクラスは、構成を理解して修正するために役立つ情報で、getMessage()printStackTrace()toString()の各メソッドの出力を拡張します。通常は、問題を修正するにはこの追加情報のみで十分ですが、十分でないときは、ログ、トレースおよび問合せの機能を使用してさらに調査できます。

各エラーについて、診断検索を実行して追加情報を利用できます。この検索は、標準的なローダーの可視性による制約は受けず、システムが認識するすべてのローダーやコード・ソースを参照できます。結果は、エラー・メッセージの一部として報告されます。

状況によっては、ローダーのランタイムが結果に基づいてリカバリ(たとえば、不足しているクラスを自動的に検索してロードする)を試行できます。ただし、これによってさらに問題が発生し、診断がいっそう困難になる可能性があります。

ClassNotFoundException

この例外は、Class.forName()ClassLoader.loadClass()などのように、名前でクラスを明示的にロードするメソッドを使用して動的なロードを行っている間に発生する可能性があります。開始しているクラス・ローダーから必要なクラスが見えないことを示しています。

トラブルシューティングと解決の方法

ClassNotFoundExceptionNoClassDefFoundErrorとほとんど同じです。1つの重要な違いは、初期ローダーの選択をJVMではなく呼出し元のコードで行うことができることで、比較的間違えやすい点です。

Class.forName(String)メソッドを使用している場合は、JREのコードが初期ローダーを選択し、常に呼出し元のローダーを選択します。これは多くの場合に正しくありません。たいていはスレッド・コンテキスト・ローダーを明示的に渡すのがよい方法です。

Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();
Class cls = loader.loadClass(name);

ローダーを直接呼び出す方が、Class.forName()の形式を使用するよりよいことに注意してください。

Class cls = Class.forName(name, true, loader);

これら2つの呼出しはどちらも指定したローダーからロードしようとしていますが、わかりやすいのは直接的な呼出しの方です。また、トレースが意図したとおりに動作することも保証されます。これは、VMによるforName()の実装によっては、ローダーを省略する場合があるためです(クラスがまだキャッシュされていない場合にのみローダーを呼び出します。ローダーは常にキャッシュ自体を調べるので、ローダーを直接呼び出す方が安全で効率的です)。

異なる初期ローダーからのクラスのロードを実験するには、LoadClassの問合せが便利です。

正しい初期ローダーが使用されていた場合は、コード・ソースが検索パスに存在しない可能性があります。詳細は、「NoClassDefFoundError」を参照してください。

NoClassDefFoundError

この例外は、あるクラスから別のクラスへの静的な依存性をVMが解決しようとしたときに発生する可能性があります。一種のLinkageErrorであり、開始しているローダーから必要なクラスが見えないことを示しています。静的な依存性の解決は最初の使用まで延期されることが多いため、このエラーは予期せず発生する場合があります。

エラー・メッセージの例

Missing class: acme.Dynamite

        Dependent class: acme.RoadRunner
Loader: acme.root:0.0.0
Code-Source: /myapps/acme/acme.jar
Configuration: <ejb> in /myapps/acme/application.xml

The missing class is available from the following locations:

1.      Code-Source: /shared/bang/0.0.0/bang.jar (from <code-source>
in j2ee/home/server.xml)

This code-source is available in loader bang:0.0.0. This
shared-library can be imported by the "acme" application.

トラブルシューティングと解決の方法

エラー・メッセージを調べます。最初の行に、見つからないクラスの名前があります。次の4つの行では、依存性を持つクラスの名前、クラスを定義しているローダー(VMによって選択された開始ローダーでもあります)、基になっているコード・ソース、およびそのローダーにコード・ソースが追加される原因となった構成オプションが示されています。次の行には診断検索の結果が示されており、問題を解決するための十分な詳細が提供されていると考えられます。

次に示すのは、診断検索によって報告されるいくつかの一般的な状態と、それを解決するための具体的な指摘です。

  • 見つからないクラスが、システムから見ることのできるどのコード・ソースにも存在しません。

    これは、多くの場合、単に別のコード・ソースを追加する必要があることを示します(さらに他のコード・ソースが必要になる可能性があります)。依存クラスの情報を使用して、構成を追加する適切なレベルを選択した後、適当なオプションを選択します(表3-1「クラスの可視性に影響を与える構成オプション」を参照)。他のアプリケーションも同じクラスを必要とする可能性がある場合は、新しい共有ライブラリの作成を検討します。作成すると、新しい共有ライブラリもインポートする必要があることに注意してください。

    この結果は、既存のコード・ソースの宣言が無効であることを意味する場合もあります。有効なファイルまたはディレクトリをポイントしていないパスが検出されると、この事実がログに記録されますが、そのレベルは通常マスクされています。すべてのメッセージを見るには、次のように設定してシステムを起動します。

    -Dclass.load.log.level=finest

    存在しないコード・ソースに関するメッセージを探し、関連するメッセージを見つけたら、構成を修正します。通常はメッセージが多いので、より簡単に検索できるファイル(たとえばloader.log)に出力を送ると便利です。

    -Dclass.load.log.file=loader.log

  • 見つからないクラスは共有ライブラリに存在していますが、共有ライブラリがインポートされていません。

    Application Server Controlコンソールを使用して、またはアプリケーションに<import-shared-library>要素を追加して、共有ライブラリをインポートします。

  • 見つからないクラスは存在しますが、それを使用するように構成されているローダーが開始ローダーの子です。

    この問題が最もよく発生するのは、アプリケーション・ルート・ローダー(たとえばEJB)にデプロイされたクラスが、Webモジュールにデプロイされたクラスに対して依存性を持っている場合です。解決するには、リファクタを行って依存性を除去するか、またはクラスを同じローダーに移動する必要があります。多くの場合、最も簡単な解決方法は、このようなクラスをWebモジュールからアプリケーション・ルートに移動することですが、反対方向の移動が可能な場合もあります。ルートにコード・ソースを追加するオプションについては、表3-1「クラスの可視性に影響を与える構成オプション」を参照してください。

    このようなクラスを移動するのではなくコピーすると、Webモジュールでsearch-local-classes-firstが有効になっている場合にはClassCastExceptionが発生する可能性があることに注意してください。

  • 見つからないクラスは存在しますが、それを使用するように構成されているローダーが関係のないアプリケーションにあります。

    この場合の理想的な解決方法は、関連するコード・ソースを既存のアプリケーションから新しい共有ライブラリに移動し、この共有ライブラリをインポートするように両方のアプリケーションを再構成することです。この方法が実際的でない場合は、コード・ソースを現在のアプリケーションにコピーしてもかまいません。構成を使用して他のアプリケーションにあるコード・ソースを直接指し示すことも可能ですが、そのアプリケーションがデプロイされない場合には障害が発生します。

    特定のローダーからのコード・ソースの検索順序を調べるには、ClassPath問合せが役に立つ場合があります。

    -Doc4j.start.query="ClassPath(acme.root)+Exit"

    SharedLibraries問合せを使用して、すべての共有ライブラリとそれをインポートするローダーの一覧を作成することもできます。

ClassFormatError

このエラーは、クラスが初めてロードされるとき(定義中)に発生する可能性があります。一種のLinkageErrorで、多くの場合、クラスが異なるバージョンのJVMに対してコンパイルされていることを示しています。

トラブルシューティングと解決の方法

エラー・メッセージでは、クラスがコンパイルされたバージョンと、現在のランタイムがサポートしているバージョンが示されています。

問題を解決するには、正しいバージョンのJVMに切り替えるか、または現在のバージョンでクラスを再コンパイルします。

LinkageError

このエラーは、クラスが初めてロードされるとき(定義中)に発生する可能性があります。一般的なLinkageErrorのサブタイプは、OC4Jクラス・ロード・システムによって特別なケースとして処理されます(NoClassDefFoundErrorおよびClassFormatErrorを参照)。それ以外のケースは、通常、次のいずれかを示しています。

  • コンパイル時に使用されたクラスのバージョンと、実行時に検出されたクラスのバージョンが一致しない。

  • 必要なネイティブ・ライブラリが見つからない。

トラブルシューティングと解決の方法

エラー・メッセージでは、実際の障害が示され、さらに、定義中に障害が発生したクラスおよびその定義が発生する原因となった依存性を持つクラスの、名前、定義しているローダー、コード・ソースおよび構成が提供されます。

メッセージがなんらかの種類のバージョン不一致(NoSuchMethodErrorなど)を示している場合、障害を解決するには、ソース・レベルの変更と再コンパイルが必要です。多くの場合、不一致はスーパークラスまたはインタフェースとサブクラスの間で発生し、比較的簡単に識別できます。

UnsatisfiedLinkErrorは、ネイティブ・ライブラリが見つからないことを意味します。通常、OC4JはRARモジュール内のネイティブ・ライブラリの構成のみをサポートします(表3-1「クラスの可視性に影響を与える構成オプション」を参照)。ライブラリがRAR内で指定されている場合、それが無効なパスである可能性があります。class.load.log.levelプロパティを使用してこのケースを検出する方法については、「NoClassDefFoundError」を参照してください。

ClassCastException

通常、この例外は次のような明らかな理由で発生します。

Object source = new Integer(0);
String target = (String) source; // Exception

ただし、クラス・ロードに関係してこの例外が発生する場合もあります。残念ながら、VMによって作成されるエラー・メッセージは通常は空で、この例外がロードに関係するものであっても、解釈して注釈を付けることができません。

複数のローダーが同じ名前でクラスを定義していると、2つの型の間のキャストがClassCastExceptionで失敗します。

import com.acme.Foo;
...
// Get the loader that resolves our static dependency
// on class Foo

ClassLoader expected = Foo.class.getClassLoader();

// Dynamically load Foo from another loader and
// create an instance

Class fooClass = aLoader.loadClass("com.acme.Foo");
Object source = fooClass.newInstance();
ClassLoader actual = fooClass.getClassLoader();

// Compare and cast

System.out.println(actual == expected); // "false"
Foo target = (Foo) source; // Exception


この場合、ローダーのインスタンスが異なるため、JVMでは2つのクラスが無関係と判断されます。

この問題の比較的よくある例は、単一のアプリケーションにおいて、EJBモジュールとEJBを使用するWebモジュールの両方でEJBインタフェースがパッケージされている場合に発生します。Webモジュールでsearch-local-classes-firstオプションが有効になっていると、EJBクラスが2回ロードされます。

トラブルシューティングと解決の方法

まず、スタック・トレースの先頭に記述されているコードを見て、キャストのターゲットの型を確認します。キャストがプリミティブ型(intやlongなど)またはJREによって定義されているクラス(String、HashMap、他のjava.クラスなど)に対するものである場合は、クラス・ロードに関係するものではないことがほぼ確実であり、通常は単なる開発者のエラーです。

次に、トレースを使用してターゲット・クラスの定義を確認します。たとえば、キャストのターゲットがcom.acme.Fooである場合は、次のような記述を使用します。

-Dclass.load.trace=class-defined:com.acme.Foo

出力では、ローダーとクラスの定義の基になっているコード・ソースが示されています。1つしかない場合、問題はクラス・ロードには関係ないと考えられます(ただし、カスタム・クラス・ローダーが使用されている場合はトレースに含まれないため、依然として問題である可能性があります)。

ターゲット・グラスの定義が2つ以上ある場合は、これらのアクセスにより例外が発生している可能性が高いです。トレース・メッセージで両方の定義に対して同じコード・ソースがリストされている場合は、ローダー間で共有されているため簡単に再調整できます。

一方、これよりさらによくあるのが、おそらく利便性のため(ほとんどの場合よくない考えです)にクラスが再パッケージされているため、またはバージョン違いのために、コード・ソースが異なる場合です。ローダーの1つがWebモジュールのものである場合は、search-local-classes-firstを無効にすれば十分である可能性があります。

コードのインスツルメントが可能な場合は、キャストのすぐ前に次のコードを追加することで、重複を確認できます(objはキャストされているオブジェクト)。

ClassLoader expected = Foo.class.getClassLoader();
System.out.println("Expected: " + expected);
ClassLoader actual = obj.getClass().getClassLoader();
System.out.println("  Actual: " + actual);

出力は、トレース・メッセージで名前が示されているローダーと一致する必要があります。objが予想される型のサブクラスである場合は、Class.getSupertype()で階層を移動することが必要になる場合があります。

重複が原因であると確認された場合は、除去する必要があります。そのためには、クラスが共有されるように調整します。クラスを、2つのローダーの共通の親、または共有ライブラリに移動します。クラスを引き続きロードするローダーを決定する際の参考として、各クラス定義の時点でのコール・スタックを見ると役に立つ場合があります。

-Dclass.load.trace=class-defined:com.acme.Foo+stack

LoaderTree問合せを使用してローダー間の関係を見ることも、役に立つ場合があります。

-Doc4j.start.query=LoaderTree

問合せは、ASControlシステムのMBeanブラウザを使用して、実行中のインスタンスに対して実行することもできます。この問合せで-verboseオプションを使用すると、詳細を見ることができます。

-Doc4j.start.query="LoaderTree(-verbose)+Exit"

DuplicateClasses問合せを使用して、潜在的な重複(異なるコード・ソース中の同じクラス名)を検索することもできます。

クラス・ロードの問題をトラブルシューティングするための問合せの使用

OC4Jで提供されているいくつかの組込み問合せを実行して、クラス・ロードの問題のトラブルシューティングを行うことができます。oc4j.start.queryシステム・プロパティを設定することでOC4Jの起動時に、またはClassLoading MBeanを介して実行時に、問合せを実行できます。


注意:

この機能は、OC4Jの今後のリリースで変更される場合があります。

使用可能なクラス・ローダー問合せのサマリー

クラス・ロードの問題のトラブルシューティングを支援するため、OC4Jには次の組込み問合せが備わっています。

使用されている例では、oc4j.start.queryシステム・プロパティの使用方法が示されていることに注意してください。このプロパティは、OC4Jの起動時にoc4j.jarのコマンドラインで設定されます。

次の問合せを使用できます。

AuditLoader

1つ以上の指定されたクラス・ローダーまたはすべての共有クラス・ローダーのコンテンツに対して様々な診断を実行します。たとえば、すべての共有クラス・ローダーを監査し、詳細な情報を出力するには、AuditLoader問合せを次のように指定します。

 AuditLoader * -verbose

引数: loaderName [loaderName]...[-verbose] [-includeJREClasses]

表3-2 AuditLoader問合せの引数

引数 説明

loaderName

監査対象のクラス・ローダーの名前。

すべての共有クラス・ローダーを監査するには、loaderNameに*を指定します。

-verbose

オプション。指定すると、詳細な情報が出力されます。

-includeJREClasses

オプション。指定すると、JREクラスが含まれます。


Callers

指定したメソッドを呼び出すすべてのクラスが返されます。オプションとして、クラス・ローダーの名前を指定して、問合せの対象を制限することができます。

たとえば、System.currentTimeMillis()を呼び出すすべてのクラスを検索するには、次の問合せを実行します。

-Doc4j.start.query=Callers(java.lang.System.currentTimeMillis()long)

次の例は、MyApp.rootクラス・ローダーから見ることのできる複数のクラス中の同じメソッドを検索します。

-Doc4j.start.query=Callers(-MyApp.root,java.lang.System.currentTimeMillis()long)

オーバーロードされたClass.forName()メソッドのいずれかのバージョンに対する呼出しを検索するには、両方のメソッドのシグネチャを引数として渡します。

-Doc4j.start.query=Callers(java.lang.Class.forName(java.lang.
String)java.lang.Class,java.lang.Class.forName(java.lang.String;boolean;java.lang.
ClassLoader)java.lang.Class)

<signature>引数に<init>を含めることで、コンストラクタを指定できます。

-Doc4j.start.query=Callers(java.util.Date.<init>())

引数: [-loaderName ] signature...

表3-3 Callers問合せの引数

引数 説明

-loaderName

オプション。指定すると、クラス・ローダーから見えるすべてのクラスで、指定したメソッドがチェックされます。

指定しないと、すべてのアプリケーション固有のクラス・ローダーのデフォルトの親であるapiクラス・ローダーから下のツリーにある、すべてのクラス・ローダーから見えるすべてのクラスがチェックされます。

signature

チェックするメソッドです。個別の引数にすることで、複数のメソッドを指定できます。

構文は次のとおりです。

class-type.method-name[parameter-type]*)return-type

複数のパラメータ・タイプはセミコロン(;)で区切ります。タイプは、完全修飾クラス名またはプリミティブ名である必要があります。戻り型がvoidの場合は、return-typeを省略できます。


ClassLoadMetrics

1つ以上の指定されたクラス・ローダー、または何も指定されていない場合はすべてのクラス・ローダーに対するメトリックをレポートします。次に例を示します。

-Doc4j.start.query=ClassLoadMetrics(MyApp.root,MyOtherApp.root)

引数: [-verbose] [<loaderName>]...


注意:

OC4J 10g(10.1.3)では、PolicyClassLoader.toString()メソッドの詳細(複数行)出力はデフォルトでオフになっています。ローダー名およびバージョンのみが戻されるようになりました。

次のシステム・プロパティのいずれかを設定し、詳細出力を再有効化することができます。

  • -Dclass.load.trace=any value

  • -Dverbose.loader.tostring=true


表3-4 ClassLoadMetrics問合せの引数

引数 説明

-verbose

オプション。指定すると、詳細なメトリックが生成されます。

loaderName

オプション。メトリックをレポートするクラス・ローダーの名前です。


ClassPath

使用中のコード・ソースがレポートされます。

引数: [-list] [loaderName]

表3-5 ClassPath問合せの引数

引数 説明

-list

オプション。指定すると、行で区切られて番号が付けられたコード・ソースのリストが生成されます。

loaderName

オプション。指定すると、クラスパスを計算する開始位置としてクラス・ローダーが使用されます。指定しないと、クラスパスのデフォルトは内部のoc4jクラス・ローダーになり、すべてのOC4Jシステム・クラスがロードされます。


Dependencies

指定したクラスのすべての依存性がレポートされます。

引数: <className> [loaderName] [-r]

表3-6 Dependencies問合せの引数

引数 説明

className

依存性をレポートするクラスの完全修飾名です。

loaderName

オプション。指定すると、依存性を決定する開始位置として指定したクラス・ローダーが使用されます。指定しないと、内部のoc4jクラス・ローダーが使用され、システム・クラスがロードされます。

-r

オプション。クラスの再帰的な検索を設定します。このオプションを使用すると実行時間が長くなる可能性があるので注意してください。


Depends

指定したクラスに依存するすべてのクラスがレポートされます。

引数: [-loaderName] <className>

表3-7 Depends問合せの引数

引数 説明

className

依存性をチェックするクラスの完全修飾名です。パッケージ全体を指定するには、リーフ名としてアスタリスク(*)を使用します。

loaderName

オプション。指定すると、クラス・ローダーから見えるすべてのクラスがチェックされます。指定しないと、apiクラス・ローダーから下位のすべてのクラス・ローダーから見えるすべてのクラスがチェックされます。


DuplicateClasses

別のコード・ソースに存在する同じ名前のクラスおよびリソースがレポートされます。

引数: [-loaderName] [-systemCodeSources]

表3-8 DuplicateClasses問合せの引数

引数 説明

-loaderName

オプション。指定すると、コード・ソース検索の開始位置としてクラス・ローダーが使用されます。指定しないと、apiクラス・ローダーから下位のすべてのクラス・ローダーから見えるすべてのクラスがチェックされます。

-systemCodeSources

オプション。指定すると、検索にシステム・コード・ソースが含まれます。


DuplicateCodeSources

同じ名前を持つコード・ソースまたは複数のサブスクライバを持つコード・ソースがレポートされます。

引数: [-digest]

表3-9 DuplicateCodeSources問合せの引数

引数 説明

-digest

オプション。指定すると、コード・ソースのビット単位の比較が実行されます。


Exit

OC4Jが実行中の場合は、プロセスを終了してOC4Jをシャットダウンします。OC4Jサーバーを稼働したままにせず、問合せのみを実行する場合に便利です。次に例を示します。

-Doc4j.start.query=LoaderTree+Exit

引数: [-force]

表3-10 Exit問合せの引数

引数 説明

-force

オプション。通常のシャットダウンのかわりにSystem.exit()の呼出しを強制的に行います。


FindResource

クラス名またはリソース・パスで指定したリソースを含むコード・ソースがレポートされます。

先頭または末尾にアスタリスク(*)を使用すると、単純なワイルドカード検索を実行できます。または、先頭に~を使用して、引数を正規表現として扱うように指示できます。パッケージのないクラスを検索するには、resourcePath引数を渡す必要があります。たとえば、クラスfooを検索するには、次のような問合せを使用します。

-Doc4j.start.query=FindResource(Foo.class)

リソース名にピリオド(.)が含まれる場合に、パッケージ(/)を含めずにリソースを検索するには、先頭にアスタリスクを使用する必要があります。たとえば、コード・ソースのルートにあるmyconfig.xmlファイルを検索するには、次の問合せを使用します。

-Doc4j.start.query=FindResource(*myconfig.xml)

引数: [-list] <resourcePath>|<className>

表3-11 FindResource問合せの引数

引数 説明

-list

オプション。ワイルドカードまたは正規表現を使用でき、一致するすべてのリソースの一覧をレポートします。

resourcePath

リソースに対する完全修飾パスです。resourcePathまたはclassNameを指定する必要があります。

className

検索するリソースの完全修飾クラス名です。resourcePathまたはclassNameを指定する必要があります。


GetResource

指定されたローダーに対してgetResource()またはgetResources()を呼び出し、結果をレポートします。

引数: resourcePath [loaderName] [-all]

表3-12 GetResource問合せの引数

引数 説明

resourcePath

リソースに対する完全修飾パスです。

loaderName

オプション。指定すると、リソース検索の開始位置としてクラス・ローダーが使用されます。指定しないと、apiクラス・ローダーから下位のすべてのクラス・ローダーから見えるすべてのクラスがチェックされます。

all

指定するとgetResources()を使用します。指定しないとgetResource()を使用します。


HttpSessions

デプロイされたアプリケーションについてアクティブなHTTPセッションをレポートします。

引数: [details]

表3-13 HttpSessions問合せの引数

引数 説明

details

オプション。指定すると、それぞれのHTTPセッションの詳細を表示します。


LeakedLoaders

クラス・ローダーのリークの検出を制御し、結果を表示します。

引数: [activate|list|deactivate]

表3-14 LeakedLoaders問合せの引数

引数 説明

activate

オプション。指定すると、クラス・ローダーのリークの検出をアクティブにします。

list

オプション。指定すると、クラス・ローダーのリークの検出結果を表示します。

deactivate

オプション。指定すると、クラス・ローダーのリークの検出を解除します。


ListQueries

OC4Jのサブクラス名oracle.oc4j.query.Queryで使用可能なすべての問合せの一覧が返されます。

引数: [-l] [queryclass]...

表3-15 ListQueries問合せの引数

引数 説明

-l

オプション。指定すると詳細を表示します。

queryclass

オプション。指定すると、各問合せに1行の説明を付けて表示します。これらの問合せのみを表示するには、1つ以上の問合せクラス名を渡します。


LoadClass

指定したクラス・ローダーを使用して、またはクラス・ローダーを指定しない場合は内部のoc4jクラス・ローダーを使用して、指定したクラスのロードを試み、結果をレポートします。有効な問合せでは、クラス・ロードのテスト・ランが実行されます。

引数: <className> [loaderName] [-forName] [-depends] [-r] [-sort]

表3-16 LoadClass問合せの引数

引数 説明

className

必須。レポートするクラスの完全修飾名です。

loaderName

オプション。指定すると、このクラス・ローダーを使用したクラスのロード試行がレポートされます。指定しないと、oc4jクラス・ローダーがデフォルトで使用されます。

-forName

オプション。試行を記録するクラス・ローダーのメソッドです。指定しないと、loader.loadClass()がデフォルトで使用されます。

-depends

オプション。指定すると、指定したクラスのすべての依存性のロードとレポートをクラス・ローダーに強制します。

-r

オプション。指定すると、すべての依存性が再帰的にロードされます。再帰にはjava.*パッケージのクラスは含まれないことに注意してください。

-sort

オプション。指定すると、依存クラスのリストがクラス名ごとに並べ替えられます。


LoadedClasses

(可能な場合)すべてのロード済のクラス名を表示します。

引数: なし

LoaderTree

指定したルート・クラス・ローダーに対する、またはルート・クラス・ローダーを指定しない場合はJREのブートストラップ・クラス・ローダーに対する、クラス・ローダー・ツリーの内容がレポートされます。デフォルトでは、ツリー内のクラス・ローダーの名前のみがレポートされます。

特定のアプリケーションのルートから下位など、クラス・ローダー・ツリーの特定の部分に注目する場合、この問合せが役に立ちます。次に例を示します。

-Doc4j.start.query=LoaderTree(MyApp.root)

クラス・ローダー・ツリー全体を取得する場合は、ルート・クラス・ローダー名を指定しません。

-Doc4j.start.query=LoaderTree

引数: [rootLoaderName] [-verbose]

表3-17 LoaderTree問合せの引数

引数 説明

rootLoaderName

オプション。ルート・クラス・ローダーの名前です。指定しないと、JREのブートストラップ・クラス・ローダー・ツリーの内容がレポートされます。

-verbose

オプション。指定すると、詳細な情報が出力されます。指定しないと、ツリー内のクラス・ローダーの名前のみがレポートされます。


Packages

1つ以上のコード・ソースに含まれたパッケージ名を表示します。

引数: [loaderName | codeSourcePath]

表3-18 Packages問合せの引数

引数 説明

loaderName

オプション。指定すると、このクラス・ローダー内のコード・ソースのみ検索されます。

codeSourcePath

オプション。指定すると、コード・ソース・パスを検索します。指定しないと、使用可能なコード・ソースをすべて検索します。


SharedLibraries

インストールされているすべての共有ライブラリとそれをインポートするクラス・ローダーの一覧が返されます。

引数: [loaderName]

表3-19 SharedLibraries問合せの引数

引数 説明

loaderName

オプション。クラス・ローダーの名前です。指定すると、そのクラス・ローダーによってインポートされる共有ライブラリの一覧が返されます。指定しないと、すべてのクラス・ローダー・インスタンスによってインポートされる共有ライブラリの一覧が返されます。


SystemProperties

システム・プロパティを表示または設定します。

引数: [<key>=<value>]...

表3-20 SystemProperties問合せの引数

引数 説明

<key>=<value>

オプション。システム・プロパティの名前および値です。指定すると、システム・プロパティの値を設定します。キー/値ペアを指定しないと、システム・プロパティの現在値が表示されます。


ThreadPools

現在のJVMについてアプリケーション・サーバー関連のスレッド・プールに関する情報を表示します。

引数: (list [<sys|req|cx>]|pool [<sys|req|cx>]|state [<sys|req|cx>][<id>])

表3-21 ThreadPools問合せの引数

引数 説明

list [<sys|req|cx>]

指定すると、すべてのスレッド・プールまたは指定されたスレッド・プールにあるすべてのスレッドを表示します。

pool [<sys|req|cx>]

指定すると、すべてのスレッド・プールまたは指定されたスレッド・プールの詳細を表示します。

state [<sys|req|cx>][<id>]

指定すると、すべてのスレッド・プール、指定されたスレッド・プール、または指定されたスレッドIDのスレッド状態をダンプします。


Threads

現在のJVMのスレッド情報を表示します。JDK 1.5では、スレッド・デッドロックをチェックするか、現在のJVMのスレッド・メモリー使用量を取得します。

引数: [list|groups|deadlock|memory]

表3-22 Threads問合せの引数

引数 説明

list

オプション。指定すると、現在のJVMのすべてのスレッドを表示します。

groups

オプション。指定すると、現在のJVMのすべてのスレッド・グループを表示します。

deadlocks

JDK 1.5専用のオプション。指定すると、現在のJVMのすべてのスレッド・デッドロックをチェックします。

memory

JDK 1.5専用のオプション。指定すると、現在のJVMのスレッド・メモリー使用量を取得します。


UnusedCodeSources

まったくデータを返していないコード・ソースがレポートされます。

引数: なし

Uptime

現在のOC4Jサーバー・インスタンスの稼働時間がレポートされます。

引数: なし

VMStat

現在のJVMの統計情報を表示します。

引数: [jps|pid|mem]

表3-23 VMStat問合せの引数

引数 説明

jps

オプション。指定すると、実行中のJavaプロセスを表示します。

pid

オプション。指定すると、現在のJVMのPIDを返します。

mem

オプション。指定すると、現在のJVMのメモリー情報を返します。


OC4J起動時の問合せの実行

oc4j.jarのコマンドラインでoc4j.start.queryシステム・プロパティを設定することで、OC4Jの起動時に問合せを実行できます。

問合せの結果は、class.load.log.fileプロパティの値として指定したファイルに、またはファイルを指定しない場合はコンソール(System.out)に出力されます。class.load.log.fileプロパティの詳細は、「クラス・ローダーのログ・レベルの設定」を参照してください。

コマンドラインではシステム・プロパティを-Dで始める必要があることに注意してください。構文は次のとおりです。

java -Doc4j.start.query=<queryName>(arg0,arg1,...) -jar oc4j.jar

問合せの名前の後に(arg0,arg1,...)を加えることで、問合せに引数を渡すことができます。引数を括弧で囲むことに注意してください。引数が複数ある場合はカンマで区切ります。


注意:

一部のUNIXシェルでは、プロパティの値の文字列(=記号より後にあるすべて)を引用符で囲む必要があります。

たとえば、DuplicateCodeSources問合せを-digest引数を指定して呼び出すには、次のように指定します。

java -Doc4j.start.query=DuplicateCodeSources(-digest) -jar oc4j.jar

+文字で区切ることで、複数の問合せを指定できます。

-Doc4j.start.query=DuplicateCodeSources(-digest)+UnusedCodeSources

ClassLoading MBeanを介した実行時の問合せの実行

ClassLoading MBeanでexecuteQuery操作を呼び出すことにより、稼働しているOC4Jインスタンスで問合せを実行できます。

このMBeanは、WebベースのApplication Server Controlコンソール・インタフェースを介してアクセスできます。OC4JにパッケージされているMBeanのアクセスと使用の詳細は、『Oracle Containers for J2EE構成および管理ガイド』を参照してください。

  1. Application Server Controlコンソールで「管理」リンクをクリックします。

  2. 「システムMBeanブラウザ」をクリックします。

  3. ナビゲーション・ペインでClassLoadingノードを展開し、singleton MBeanインスタンスを選択します。

  4. 右側のペインで「操作」タブをクリックし、executeQuery操作をクリックします。


    注意:

    2つのバージョンのexecuteQuery操作が公開されています。2つのパラメータを受け取るバージョンをクリックしてください。(queryClassDataパラメータは、システムMBeanブラウザからは設定できません。)

  5. queryClassNameに対する値として、実行する問合せの名前を入力します。たとえば、LoaderTreeなどと入力します。

  6. 「queryArguments」アイコンをクリックし、指定する引数ごとに新しい行を追加します。引数は括弧で囲まないでください。括弧は、操作が呼び出されるときに自動的に追加されます。引数の指定が終了したら、「OK」をクリックします。

  7. 「起動」ボタンをクリックして、操作を呼び出します。

問題のトラブルシューティングに役立つクラス・ロード・イベントのトレース

OC4Jで提供されているclass.load.traceシステム・プロパティを設定すると、クラスのロード、クラス・ローダーのライフサイクルおよびコード・ソースのライフサイクルのイベントをトレースできます。生成されるトレース出力は、クラスのロードに関する問題のトラブルシューティングに非常に役立ちます。


注意:

この機能は、OC4Jの今後のリリースで変更される場合があります。

class.load.traceプロパティは、OC4Jの起動時に設定されます。構文は次のとおりです。

class.load.trace=<event>[[:<string-filter>[,<string-filter>]] |
 [~<pattern-filter>]]

  • <event>はトレースするイベントです。有効な値については、表3-24を参照してください。

    +文字を使用すると、複数のイベント値を連結できます。

    -Dclass.load.trace=class+loader
    
    
  • <string-filter>は、トレースの出力を制御するために適用するフィルタです。最初のフィルタとイベントをコロン(:)で区切ることに注意してください。トレース出力を制御するために適用できるフィルタの種類の詳細は、「トレース出力を制御するためのフィルタの使用」を参照してください。

    フィルタが複数ある場合はカンマで区切ります。

    -Dclass.load.trace=class:com.acme.Foo,com.acme.Bar
    
    
  • <pattern-filter>は、正規表現として解釈される単一のフィルタです。フィルタの前に文字~を付けることに注意してください。


注意:

  • コマンドラインではシステム・プロパティを-Dで始める必要があります。次に例を示します。

    java -Dclass.load.trace=loader -jar oc4j.jar
    
    
  • スタンドアロンのOC4Jの構成では、前の例で示されているように、システム・プロパティをoc4j.jarのコマンドラインで直接設定します。

  • Oracle Application Serverの構成では、システム・プロパティを<data>要素で設定します。このとき、id属性は、そのOC4Jインスタンスに対するopmn.xmlファイルの"java-options"です。次に例を示します。

    <data id="java-options" value="-Dejb3=true  -Dclass.load.trace=class+loader"/>
    

トレースの出力は、デフォルトではコンソールに表示されますが、class.load.log.fileシステム・プロパティを使用して、指定したファイルに書き込むこともできます。次に例を示します。

java -Dclass.load.log.file=C:\logs\logfile.txt -jar oc4j.jar

表3-24 class.load.traceシステム・プロパティの値

説明

all

すべてのトレース・モードをアクティブ化します。この値を設定すると、出力の量が増えるためにOC4Jのパフォーマンスに若干影響が出る可能性があることに注意してください。

none

すべてのトレース・モードを無効にします。

class

すべてのクラス・ロード検索イベントをトレースします。

class-defined

指定したクラスがクラス・ローダーによって最初にロードされるすべてのイベントをトレースします。その後、オブジェクトは以降のクラス・ローダーによる使用のためにキャッシュされます。

class-found

指定したクラスが検出されたすべての検索イベントをトレースします。

class-not-found

指定したクラスが検出されなかったすべての検索イベントをトレースします。

code-source

すべてのコード・ソース・ライフサイクル・イベントをトレースします。

code-source-create

コード・ソース・オブジェクトが最初に初期化されたイベントをトレースします。メモリー内に作成されるコード・ソースのインスタンスは1つのみです。その後、このオブジェクトは、必要とするすべてのクラス・ローダーによって共有されます。

code-source-dependency

すべてのコード・ソースについて、アーカイブ内にパッケージされているMANIFEST.MFファイルで宣言されている拡張依存性が検出された、または検出されなかったイベントをトレースします。

code-source-dependency-satisfied

すべてのコード・ソースについて、アーカイブ内にパッケージされているMANIFEST.MFファイルで宣言されているすべての拡張依存性が検出されたイベントをトレースします。

code-source-dependency-not-satisfied

すべてのコード・ソースについて、アーカイブ内にパッケージされているMANIFEST.MFファイルで宣言されているすべての拡張依存性が検出されなかったイベントをトレースします。

code-source-manifest

すべてのコード・ソースについて、MANIFEST.MFファイルがアーカイブ内にパッケージされていて、すべてのクラスパスや拡張宣言などが処理されているイベントをトレースします。

code-source-state

次の2つのコード・ソース状態に対するイベントをトレースします。

  • オープン: コード・ソースが、検索されているか、またはクラス・ローダーによって使用されています。

  • クローズ: コード・ソースは現在クラス・ローダーによって使用されておらず、基本的に受動化状態になっています。

code-source-destroy

コード・ソース・オブジェクトが破棄されているイベントをトレースします。

loader

すべてのクラス・ローダー・ライフサイクル・イベントをトレースします。

loader-create

クラス・ローダー・オブジェクトのインスタンス化イベントをトレースします。

loader-commit

クラス・ローダー・オブジェクトが作成され、コード・ソースからクラスを移入されたイベントをトレースします。

loader-finalize

クラス・ローダー・オブジェクトに対してfinalize()メソッドが呼び出され、オブジェクトがアクセス不能になったイベントをトレースします。

loader-close

クラス・ローダー・オブジェクトがJVMによるガベージ・コレクションの処理中であるイベントをトレースします。

loader-destroy

クラス・ローダー・オブジェクトが破棄されているイベントをトレースします。

resource

すべてのリソース検索イベントをトレースします。

resource-found

リソースが検出されたすべてのリソース検索イベントをトレースします。

resource-not-found

リソースが検出されなかったすべてのリソース検索イベントをトレースします。

stack

すべてのイベントにスタック・トレースを追加します。

helpまたは?

ヘルプ・テキストをコンソールに表示します。


トレース出力を制御するためのフィルタの使用

class.load.traceシステム・プロパティは、イベント・トレースの出力をより制御しやすくするためのフィルタの使用をサポートします。構文は次のとおりです。最初のフィルタとトレース対象のイベントをコロン(:)で区切ることに注意してください。

<event>[[:<string-filter>[,<string-filter>]] | [~<pattern-filter>]]

表3-25は、サポートされるイベント・フィルタの種類についての説明です。

表3-25 サポートされるトレース出力フィルタ

イベント サポートされるフィルタ

class

  • 完全一致



    イベントをトレースするクラスの完全修飾名を指定します。次の例では、com.acme.Dynamiteクラスのロードのみをトレースします。

    -Dclass.load.trace=class:com.acme.Dynamite
    
    
  • 接頭辞または接尾辞の一致



    先頭または末尾にアスタリスク(*)を付けて、文字列を接頭辞または接尾辞として扱います。次に例を示します。

    -Dclass.load.trace=class:com.acme.*
    -Dclass.load.trace=code-source:*foo.jar
    
    
  • 正規表現の一致



    チルダ(~)を使用することで、文字列を正規表現として扱います。.*構文は任意の数の文字が表現と一致できることを示すことに注意してください。

    次の例では、utilを含むクラス名に対するクラス・ロード・イベントをトレースします。

    -Dclass.load.trace=class~.*util.*
    
    
  • クラス・ローダーの一致



    フィルタの文字列をloader.で始めると、残りの文字列はクラス・ローダー名として扱われます。

    次の例では、すべてのアプリケーション固有のクラス・ローダーのデフォルトの親であるapiクラス・ローダーによって実行されるクラスのロードのみをトレースします。

    -Dclass.load.trace=class:loader.api
    
    

code-source

  • フルパス



    イベントをトレースするコード・ソースのフルパスを指定します。次に例を示します。

    -Dclass.load.trace=code-source:/C:/oc4j/xdk/lib
    
    
  • 部分パス



    先頭または末尾にアスタリスク(*)を付けて、文字列を接頭辞または接尾辞として扱います。次の例では、com.acmeパッケージ内のクラスのロードのみをトレースします。

    -Dclass.load.trace=code-source:*/acme.jar
    -Dclass.load.trace=code-source:/C:/oc4j/*
    
    
  • 正規表現の一致



    チルダ(~)を使用することで、文字列を正規表現として扱います。.*構文は任意の数の文字が表現と一致できることを示すことに注意してください。

    次の例では、fooアプリケーションに対するcode-source-createイベントをトレースします。

    -Dclass.load.trace=code-source-create~.*/foo/.*
    

loader

  • 完全一致



    イベントをトレースするクラス・ローダーの完全な名前(name.name:version)を指定します。次に例を示します。

    -Dclass.load.trace=loader:oracle.jdbc:10.1.0_2
    
    
  • 接尾辞の一致



    末尾にアスタリスク(*)を付けて、文字列を接尾辞として扱います。次に例を示します。

    -Dclass.load.trace=loader:oracle.jdbc:*
    
    
  • 正規表現の一致



    チルダ(~)を使用することで、文字列を正規表現として扱います。.*構文は任意の数の文字が表現と一致できることを示すことに注意してください。

    次の例では、アプリケーション・ルート・クラス・ローダーに対するcreateイベントをトレースします。

    -Dclass.load.trace=loader-create~.*root.*
    

resource

  • フルパス



    リソースに対するフルパスを指定します。次に例を示します。

    -Dclass.load.trace=resource:META-INF/services/
      javax.xml.parsers.DocumentBuilderFactory.
    
    
  • 部分パス



    先頭または末尾にアスタリスク(*)を付けて、文字列を接頭辞または接尾辞として扱います。次の例では、com.acmeパッケージ内のクラスのロードのみをトレースします。

    -Dclass.load.trace=resource:*Messages_en.properties
    -Dclass.load.trace=resource: oracle/oc4j/admin/jmx/model/*
    
    
  • 正規表現の一致



    チルダ(~)を使用することで、文字列を正規表現として扱います。.*構文は任意の数の文字が表現と一致できることを示すことに注意してください。

    次の例では、パスにsecurityが含まれるプロパティ・ファイルに対するすべてのリソース検索をトレースします。

    -Dclass.load.trace=resource~.*security.*properties
    

クラス・ローダーのログ・レベルの設定

デフォルトでは、クラス・ローダーのLoggerメッセージは、CONFIGのJavaログ・レベルでフィルタされます。必要であれば、class.load.log.levelシステム・プロパティを使用してログ・レベルを変更できます。次の表3-26は、このプロパティで設定できる値の一覧です。

たとえば、ログ・レベルをSEVEREに設定するには次のように指定します。

-Dclass.load.log.level=severe

トレース関連のメッセージはINFOのログ・レベルで作成されることに注意してください。したがって、これらのメッセージがLoggerの出力からフィルタで除外されるのを防ぐため、INFOより上のログ・レベル(たとえばWARNING)には設定しないでください。

表3-26 class.load.log.levelシステム・プロパティの値

説明

all

すべてのログ・メッセージを出力します。

severe

SEVEREレベルのメッセージのみを出力します。

warning

WARNINGレベル以上のメッセージを出力します。

info

INFOレベル以上のメッセージを出力します。ログ・レベルをinfoより低く(たとえばfiner)設定すると、トレース出力がLoggerの出力からフィルタされます。

config

CONFIGレベル以上のメッセージを出力します。デフォルトのログ・レベルです。

fine

FINEレベル以上のメッセージを出力します。

finer

FINERレベル以上のメッセージを出力します。

finest

FINESTレベル以上のメッセージを出力します。

off

すべてのログ・メッセージを抑止します。