12.3 スキーマ・オブジェクトの解決

すべてのJavaクラスには、他のクラスへの参照が含まれています。従来のJVMは、CLASSPATHで指定されたディレクトリ、ZIPファイルおよびJARファイル内でクラスを検索します。一方、Oracle JVMはスキーマでクラス・スキーマ・オブジェクトを検索します。データベース内のクラスごとにリゾルバ仕様があり、これは、CLASSPATHに相当するOracle Databaseの仕様です。たとえば、alphaというクラスのリゾルバ仕様は、alphaで使用するクラスを検索するスキーマをリストします。リゾルバ仕様はクラスごとにあるのに対し、従来のJVMのCLASSPATHはすべてのクラスを対象にしたグローバルな仕様であることに注意してください。

各クラス・スキーマ・オブジェクトには、リゾルバ仕様の他に、クラス間参照バインドのリストがあります。参照リストの各項目の内容は、別のクラスへの参照と次のいずれかです。

  • クラスで参照を使用するときにコールするクラス・スキーマ・オブジェクトの名前

  • 参照が未解決かどうかを示すコード、つまり、対象のスキーマ・オブジェクトが認識されているかどうかを示すコード

参照リストの保守は、Oracle Databaseの機能の1つであるリゾルバが行います。クラス内のクラス間参照ごとに、リゾルバは、クラスのリゾルバ仕様で指定されたスキーマで、参照を満たす有効なクラス・スキーマ・オブジェクトを検索します。すべての参照が解決されると、リゾルバによりこのクラスは「有効」とマークされます。解決処理が行われていないクラス、または正常に解決できなかったクラスは「無効」とマークされます。無効になったスキーマ・オブジェクトに依存しているクラスも、最初のクラスが無効とマークされるときに無効とマークされます。つまり、無効化は1つのクラスからそのクラスを使用しているクラス群、そのクラス群を使用しているクラス群というように、上方に連鎖します。無効なクラスに依存するクラスを解決するとき、リゾルバは最初に参照先クラスを解決しようとします。これは、単に解決処理が行われていないために、無効とマークされている場合があるためです。リゾルバは、有効とマークされているクラスを解決しません。

開発者は、loadjavaツールでクラスを解決するように指示することができ、実行時まで解決を延期することもできます。無効とマークされているクラスを別のクラスでロードしようとすると、自動的にリゾルバが実行されます。実行時以前に解決すると、欠落しているクラスを早期に検出できます。実行時に解決できない場合は、ClassNotFound例外が生成されます。また、次の理由で実行時に解決できない場合があります。

  • データベース・リソースの不足(クラスのツリーが非常に大きい場合)

  • 循環依存が原因のデッドロック

loadjavaツールには、次の2つの解決モードがあります。

  • Load-and-resolve

    -resolveオプションを指定して、コマンドラインで指定したすべてのクラスをロードし、無効とマークしてからクラスを解決します。相互に参照しているクラス群を初めてロードするときは、このモードを使用し、通常は、孤立したクラスを再ロードするときもこのモードを使用します。このモードでは、すべてのクラスをロードしてから解決することによって、この後でクラスの参照先クラスがコマンドの実行中にロードされる場合でも、エラー・メッセージの発生を回避できます。

  • Load-then-resolve

    このモードでは、実行時に各クラスを解決します。-resolveオプションは指定しません。

    ノート:

    Javaコンパイラと同様に、loadjavaツールはクラスへの参照を解決しますが、リソースへの参照は解決しません。したがって、クラスに必要なリソース・ファイルを正しくロードする必要があります。

可能な場合は、すべてのクラスのロードが完了するまで、解決を延期してください。延期することによって、使用するクラスがロードされていないために、リゾルバによりそのクラスが無効とマークされるのを回避できます。