クラス・ロード例外
アプリケーションの開発時、あるいはインストール済みアプリケーションの開始時に発生するクラス・ロード・エラーの種類を特定してください。
ClassCastException
クラス・キャスト例外は、以下の条件が存在する場合に発生し、次のアクションによって修正することができます。
- ソース・オブジェクトのタイプは、 ターゲット・クラス (タイプ) のインスタンスではありません。
- ソース・オブジェクト (クラス) をロードするクラス・ローダーが、ターゲット・クラスをロードするクラス・ローダーと異なります。
- アプリケーションが、 絞り込み操作を実行しないか、または実行が不適切です。
- ソース・オブジェクトのタイプは、 ターゲット・クラス (タイプ) のインスタンスではありません。
- これは、典型的なクラス・キャスト例外です。 キャスト・ステートメントの
ソース・オブジェクトがターゲット・クラス (タイプ) のインスタンスではないと診断するには、ソース・オブジェクト・クラスのクラス・シグニチャーを調査し、その先祖にターゲット・クラスを含まないこと、およびソース・オブジェクト・クラスが、ターゲット・クラスと異なることを確認します。 クラス情報を取得するには、単純な print ステートメントをコードに挿入します。 例:
または、javap コマンドを使用します。 例:System.out.println( source.getClass().getName() + ":" + target.getClass().getName() );javap java.util.HashMap Compiled from "HashMap.java" public class java.util.HashMap extends java.util.AbstractMap implements java.util.Map,java.lang.Cloneable,java.io.Serializable { - ソース・オブジェクト (クラス) をロードするクラス・ローダーが、ターゲット・クラスをロードするクラス・ローダーと異なります。
- ソース・オブジェクトのタイプがターゲット・クラスのインスタンスであるとすると、
クラス・キャスト例外が発生するのは、ソース・オブジェクトのクラスをロードするクラス・ローダーが、ターゲット・クラスをロードするクラス・ローダーと異なる場合です。 この状況は、ターゲットクラスが複数のクラスローダーのクラスパス上で可視である場合に発生する可能性があります。 WebSphere® Application Server実行時環境。 この問題を訂正するには、クラス・ローダーの問題を診断するのに使用する「検索」および「クラス名で検索
(Search by class name)」コンソール・ページを使用します。
- クリックアクセスするには検索ページ。
- 「検索タイプ」に「クラス/パッケージ」」を選択します。
- 「検索語」に、2 つのクラス・ローダーによってロードされるクラスの名前を入力します。
- 「OK」をクリックします。 「クラス名で検索 (Search by class name)」ページが表示され
、クラスをロードするすべてのクラス・ローダーがリストされます。
複数のクラス・ローダーがリストされた場合は、ターゲット・クラスが複数のクラス・ローダーによってロードされています。 ソース・オブジェクトはターゲット・クラスのインスタンスであるため、 ソース・オブジェクト・クラスをロードするクラス・ローダーが、ターゲット・クラスをロードするクラス・ローダーと異なります。
- 戻るクラスローダービューアページクラスパスを調べて、2 つの異なるクラス ローダーがクラスをロードする理由を特定します。
- 該当するクラス・ローダーのみにクラスが見えるように、コードを修正します。
- アプリケーションが、 絞り込み操作を実行しないか、または実行が不適切です。
- クラス・キャスト例外は、アプリケーションがリモート・エンタープライズ Bean (EJB) オブジェクトを解決しているときに、
アプリケーション・コードが必要な絞り込み操作を実行しないために起こります。 アプリケーションは、リモート・オブジェクトを検索した後で絞り込み操作を実行する必要があります。 アプリケーションを調査し、アプリケーションがリモート・オブジェクトを検索するかどうかを判別し、検索する場合には、検索の結果を絞り込みメソッドに送信します。
絞り込みメソッドは、EJB 2.0 プログラミング・モデルに従って呼び出される必要があります。 特に、絞り込みメソッドに送信されるターゲット・クラスは、EJB の正確な最派生インターフェースでなければなりません。 これにより、クラスキャスト例外も発生します。 WebSphere Application Server実行時環境。 アプリケーションを調査し、絞り込みメソッドに送信されるターゲット・クラスが、 正確な EJB タイプではなく、指定された EJB のスーパー・インターフェースとなっていないか判別します。そうである場合は、正確な EJB インターフェースで絞り込みを呼び出すようにアプリケーションを修正します。
最後に、絞り込み操作中に クラス・キャスト例外が発生する場合は、絞り込みメソッドが、ローカル・エンタープライズ Bean ではなく、 リモート EJB の検索結果に適用されていることを確認します。 絞り込みは、ローカル検索には使用されません。 アプリケーションまたはモジュールのデプロイメント記述子を検査して、絞り込み検索対象のオブジェクトがローカル・オブジェクトでないことを確認します。
ClassNotFoundException
class not found exception は、以下の条件が存在する場合に発生し、次のアクションを実行するこ とによって修正できます。
- クラスが コンテキスト・クラス・ローダーの論理クラスパスで可視ではありません。
- 見つからないクラスは、現在のスレッドに関連付けられている
クラス・ローダーの論理クラスパスに存在しません。 論理クラスパスは、ロード操作がクラス・ローダーで呼び出されたときに検索されるすべてのクラスパスの累積です。 この問題を修正するには、検索ページを使用して、クラス名と Java™ アーカイブ (JAR) 名で検索します。
- クリックアクセスするには検索ページ。
- 「検索タイプ」に「クラス/パッケージ」」を選択します。
- 「検索語」に、見つからないクラス名を入力します。
- 「OK」をクリックします。 「クラス名で検索 (Search by class name)」ページが表示され 、クラスをロードするすべてのクラス・ローダーがリストされます。
- ページを調べてそのクラスがリストに存在しているかどうか確認します。
- リストにそのクラスがない場合は、「検索」ページに戻ります。 「検索語」に、クラスの .jar ファイルの名前を入力し、「検索タイプ」で「JAR/ディレクトリー (JAR/Directory)」を選択します。
- 「OK」をクリックします。 「Search by Path」ページが表示され、JAR ファイルを格納しているすべてのディレクトリーがリストされます。
JAR ファイルがリストにない場合、そのクラスは論理クラスパスにないか、読み取り不能か、代替クラスが既にロードされている場合があります。 クラスを、ロードできるロケーションに移動します。
- アプリケーションが クラス・ローダー API を間違って使用します。
- アプリケーションは、クラス・ローダーのインスタンスを取得し、
そのクラス・ローダーの loadClass メソッドを呼び出すか、またはそのクラス・ローダーで Class.forName(class_name、initialize、class_loader) を呼び出すことができます。 アプリケーションで、クラス・ローダーのアプリケーション・プログラミング・インターフェース (API) を間違って使用している場合があります。 例えば、
クラス名が間違っている、クラスがそのクラス・ローダーの論理クラスパスにない、
または間違ったクラス・ローダーを使用している、などが考えられます。
この問題を 解決するには、クラスが存在するかどうか、およびアプリケーションが適切にクラス・ローダー API を使用しているかどうかを判別します。 以下の手順に従ってくださいクラスはコンテキスト クラス ローダーの論理クラスパス上に表示されませんクラスがロードされているかどうかを判断します。 クラスがロードされていなかった場合は、アプリケーションの修正を試みてクラスがロードするかを確認します。 クラスが適切なアクセス権のある持つクラスパスにあり、別のファクトリ ー・クラスによってオーバーライドされていない場合は、クラスをロ ードするのに使用する API を調べます。
- クリッククラスローダーにアクセスする検索ページ。
- 「検索タイプ」に「クラス/パッケージ」」を選択します。
- 「検索語」に、クラス名を入力します。
- 「OK」をクリックします。 「クラス名で検索 (Search by class name)」ページが表示され 、クラスをロードするすべてのクラス・ローダーがリストされます。
- ページを調べてそのクラスがリストに存在しているかどうか確認します。
- クラスがリストにあり、ClassNotFound 例外がスローされた場合は、.jar ファイルかクラスは正しいコンテキストにないか、現行コンテキストで間違った API 呼び出しが使用されています。リストにそのクラスがない場合は、「検索」ページに戻り、以下を 実行します。
- 例外を生成したクラス、すなわち、Class.forName を呼び出すクラスを検索します。
- どのクラス・ローダーがクラスをロードするかを確認します。
- クラス・ローダーがアクセス権を持っているかどうか、またはクラス・ローダーのクラスパスを実行することによって見つからないクラスをロードできるかどうかを判別します。
- 従属クラスが可視ではありません。
- クラス・ローダー clsldr がクラス cls をロードする場合、
Java 仮想マシン (JVM) は、clsldr を呼び出して cls が従属するクラスをロードします。 従属クラスは、clsldr の論理クラスパス上で可視である必要があります。可視でない場合は、例外が発生します。 この状態は通常、ユーザーがWebSphere Application ServerクラスをJVMから見えるようにするか、アプリケーションクラスをJVMまたはWebSphere拡張クラスローダー。 例:
- クラス A はクラス B に従属しています。
- クラス A は、WebSphere 拡張クラス・ローダーに見えています。
- クラス B は、WAR モジュール・クラス・ローダーのローカル・クラスパス上では見えていますが、WebSphere 拡張クラス・ローダーのクラスパス上では見えていません。
JVM は、WebSphere 拡張クラス・ローダーを使用してクラス A をロードする場合、同じクラス・ローダーを使用してクラス B のロードを試み、結局、クラスが見つからないという例外を作成します。
以下の方法でこの問題を解決します。
- アプリケーション固有のクラスを適切なアプリケーションのクラス・ローダーに見えるようにします。
- 見つからなかったクラス (クラス B) を検索します。
- クラスBが適切な場所にある場合、クラスを検索クラス ローダー ビューアーで依存クラス (クラス A) をロードします。
- クラスがロードされ、ClassNotFound例外がスローされた場合、.jarファイルまたはクラスが適切なコンテキストにないか、現在のコンテキストで間違った API 呼び出しが使用されました。クラスが見つからなかった場合は、以下を実行します。
- 例外を生成したクラス、すなわち、Class.forName を呼び出すクラスを検索します。
- どのクラス・ローダーがクラスをロードするかを確認します。
- クラス・ローダーがアクセス権を持っているかどうか、またはクラス・ローダーのクラスパスを実行することによって見つからないクラスをロードできるかどうかを判別します。
- 呼び出し元のクラス (クラス B) が JVM または WebSphere 拡張クラス・ローダーに見えていることを確認します。
NoClassDefFoundException
no class definition found 例外は、以下の条件が存在する場合に発生し、次のアクシ ョンを実行することによって修正できます。
- そのクラスが論理クラスパスにありません。
- 参照するClassNotFoundException詳細については。
- クラスはロードができません。
- クラスがロードできないのには、さまざまな理由があります。 理由には、従属クラスをロードできない、従属クラスのフォーマットが間違っているか、クラスのバージョン番号が違うといったものがあります。
UnsatisfiedLinkError
リンケージ・エラーは以下の条件が存在する場合に発生し、次のアクションを実行することによって修正できます。
- ユーザーのアクションにより、エラーが発生しました。
System.mapLibraryName間違ったライブラリファイルを返します。- ネイティブ・ライブラリーが既にロードされています。
- 従属したネイティブ・ライブラリー使用されました。
- ユーザーのアクションにより、エラーが発生しました。
いくつかのユーザー・アクションがリンケージ・エラーを発生させる場合があります。
- ライブラリーの拡張名がそのプラットフォームに対して正しくありません。
ライブラリにはダイナミックリンクライブラリ名が付けられますlibrary_name.dll。
図書館の名前はlibrary_name.soまたはlibrary_name.a。- System.loadLibrary に正しくないパラメーターが渡されています。
ダイナミックリンクライブラリをロードするにはName.dll、
Nameに渡される必要がありますloadLibrary電話。
ライブラリをロードするにはlibName.soまたはlibName.a、libNameロードライブラリに渡されます。- ライブラリーが可視ではありません。
- 最良の方法は、JVM クラス・ローダーを使用して、ネイティブ・ライブラリーを検索またはロードすることです。 WebSphere Application ServerJavaライブラリパスを出力します(java.library.path ) を起動します。 JVM クラス・ローダーでライブラリーをロードする場合は、Java ライブラリー・パスに、ネイティブ・ライブラリー・ファイルを含むパスが存在することを確認します。 このパスが存在しない場合は、プラットフォーム固有のネイティブ・ライブラリー環境変数、
またはサーバー・プロセス定義の java.library.path システム・プロパティーにパスを追加します。
一般的に、Java仮想マシンはfindLibrary( )クラスローダーxxxを呼び出すクラスをロードしますSystem.loadLibrary( )。 もしxxx .findLibrary() が失敗すると、Java 仮想マシンは JVM クラス ローダーを使用してライブラリを見つけようとし、JVM ライブラリ パスを検索します。 ライブラリーが見つからない場合は、Java 仮想マシンが UnsatisfiedLinkError 例外を作成します。
したがって、WebSphereクラスローダーはネイティブライブラリを見つけることを目的としていますmyNativeLibライブラリは、
nativelibpath呼び出すクラスをロードするクラスローダーのSystem.loadLibrary(myNativeLib ) この方法は、次の状況で必要または望ましいです。データソースプロバイダのネイティブライブラリは、
nativelibpathのWebSphere拡張クラスローダー。 この場合は、ネイティブ・ライブラリーを含むパスを、 データ・ソース・プロバイダー構成の「ネイティブ・ライブラリー・パス (Native library path)」設定に追加します。- 共有ライブラリーの構成には、「ネイティブ・ライブラリー・パス (Native library path)」があります。 共有ライブラリーは、アプリケーション固有ライブラリーのバージョン管理が可能なため、共有ライブラリー・コードが使用するすべてのネイティブ・ライブラリーのパスを、共有ライブラリー構成で指定することを検討します。
正しい WebSphere クラス・ローダーが、System.loadLibrary() を呼び出すクラスをロードすること、およびネイティブ・ライブラリーが「ネイティブ・ライブラリー・パス (Native library path)」設定で可視であることを確認します。
![[AIX HP-UX Solaris]](../images/unix.gif)
- System.mapLibraryName は間違ったライブラリー・ファイルを戻します。
- 共有ライブラリーをロードする場合、JVM は mapLibraryName(libName) を呼び出し、 libName をプラットフォーム固有の名前に変換します。 の上AIX®、 HP-UXまたはSolarisオペレーティングシステムでは、この呼び出しは間違った拡張子のファイル名を返す可能性があります(たとえば、libName.soそれよりもlibName.a)。 この問題をデバッグするには、System.mapLibraryName() を呼び出すプログラムを作成し、それが正しいファイル名を戻すことを確認します。
- ネイティブ・ライブラリーが既にロードされています。
- この状態は、以下のエラーのうちのいずれかの結果で起こることがあります。
- ユーザー・エラー
- System.loadLibrary に対する複数の呼び出しをチェックし、余分な呼び出しを除去します。
- アプリケーション再始動時のエラー
- JVM には制限があり、ネイティブ・ライブラリーをロードできるのは、1 度に 1
つのクラス・ローダーのみです。 停止済みアプリケーションからガーベッジ・コレクターがクラス・ローダーをクリーンアップする前に
アプリケーションを再始動すると、エラーが発生します。 ネイティブ・ライブラリーをロードするクラスを移動する場合には、
そのネイティブ・ライブラリーに依存するすべてのクラスとそれらの依存関係も移動する必要があります。
このエラー状態を訂正するには、ネイティブ・ライブラリーのロードを、再ロードを行わないクラス・ローダーに移動します。以下の手順で移動してください。
- ネイティブ・ライブラリーをロードする、またはネイティブ・メソッドを保持するすべてのアプリケーション・クラスを、位置指定します。
- ステップ 1 のクラスの従属クラス (ロギング・パッケージなど) を識別します。
- サーバーに関連付けられた共有ライブラリーを作成するか、または個別の共有ライブラリーを作成します。
- ステップ 1 および 2 でクラス用にロードされた JAR ファイルを、アプリケーションから、ステップ 3 で作成した共有ライブラリーへ移動します。
- 変更を保存します。
- アプリケーションを再デプロイし、シナリオを再実行します。
サーバーを有効範囲としたライブラリー内のクラスは、 各サーバーのライフサイクルで一回ロードされます。 これにより、アプリケーションのライフサイクルにかかわらず、アプリケーションで必要なネイティブ・ライブラリーが Java 仮想マシンごとに必ず 1 回ロードされることになります。
- 従属したネイティブ・ライブラリー使用されました。
- 従属したネイティブ・ライブラリーが JVM クラス・ローダーによって検索またはロードされる必要があります。 つまり、ネイティブ・ライブラリー NL が別のネイティブ・ライブ
ラリー DNL に従属している場合、JVM クラス・ローダーは Java ライブラリー・パス上の DNL を検索する必要があります。 これは、NL をロードする場合に JVM がネイティブ・コードを実行するためです。DNL への従属がある場合、JVM ネイティブ・コードは JVM クラス・ローダーを呼び出すだけで従属を解決することができます。 WebSphere クラス・ローダーが従属したネイティブ・ライブラリーをロードできません。
Java ライブラリー・パス (LIBPATH) を定義するプラットフォーム固有の環境変数を変更して、 未解決のネイティブ・ライブラリーを含むパスを組み込みます。