| 目次 | 前の項目 | 次の項目 | Java Remote Method Invocation |
RMIClassLoader クラスjava.rmi.server.RMIClassLoaderクラスは、RMI でネットワークベースのクラスのロードをサポートする、一連の public かつ static のユーティリティメソッドを提供します。これらのメソッドは、RMI 内部の整列化ストリームによって呼び出され、RMI パラメータおよび戻り値の型のクラスを動的にロードしますが、RMI でのクラスのロードの動作を真似るために、アプリケーションから直接呼び出されることもあります。RMIClassLoaderクラスには、パブリックにアクセス可能なコンストラクタがないため、インスタンスを生成できません。
package java.rmi.server;
public class RMIClassLoader {
public static String getClassAnnotation(Class cl);
public static ClassLoader getClassLoader(String codebase)
throws java.net.MalformedURLException, SecurityException;
public static Object getSecurityContext(ClassLoader loader);
public static Class loadClass(String name)
throws java.net.MalformedURLException,
ClassNotFoundException;
public static Class loadClass(String codebase, String name)
throws java.net.MalformedURLException,
ClassNotFoundException;
public static Class loadClass(URL codebase, String name)
throws java.net.MalformedURLException,
ClassNotFoundException;
}
getClassAnnotationメソッドは、ネットワークのコードベースパスを表すStringを返します。 このコードベースパスは、指定されたクラスの定義をダウンロードするためにリモートエンドポイントが使用します。RMI ランタイムは、getClassAnnotationメソッドから返されたStringオブジェクトを、整列化ストリーム内のクラス記述子の注釈として使います。このコードベース文字列の形式は、スペースで区切ったコードベース URL 文字列のパスです。提供されたクラスのクラスローダに応じて、次のようにコードベース文字列が返されます。
| - | 「システムクラスローダ」 (アプリケーションの「クラスパス」にクラスをロードするために使用され、ClassLoader.getSystemClassLoader メソッドから返されるクラスローダ) |
| - | インストール型拡張機能用のクラスローダなどの「システムクラスローダ」の親 |
| - | null (JVM クラスのロード用の「ブートクラスローダ」) |
java.rmi.server.codebase プロパティの値が返されるか、プロパティが設定されていなければ null が返されます。
- それ以外の場合で、クラスローダが
java.net.URLClassLoaderクラスのインスタンスである場合、返されるコードベース文字列は、クラスローダのgetURLsメソッドを呼び出すことによって返される、外部形式のスペースで区切られた URL の一覧です。RMIClassLoader.loadClassメソッドの 1 つを呼び出すサービスを提供するために、URLClassLoader が RMI ランタイムによって作成された場合は、関連付けられたコードベース文字列の取得にアクセス権は必要ありません。これが任意のURLClassLoaderのインスタンスである場合、呼び出し側は、getURLsメソッドから返される各URLのインスタンスであるopenConnection().getPermission()を呼び出すことによって指定される、そのコードベースパス内のすべての URL に接続可能なアクセス権が必要です。- クラスローダが
URLClassLoaderのインスタンスでない場合は、java.rmi.server.codebaseプロパティの値が返されるか、またはこのプロパティが設定されていない場合は、nullが返されます。
getClassLoaderメソッドは、所定のコードベース URL パス (スペースで区切られた URL のリスト) からクラスをロードするクラスローダを返します。そのクラスローダは、loadClass(String,String)メソッドが特定のコードベースからクラスをロードするために使用するものです。同じコードベース URL パスを持つクラスローダがすでに RMI ランタイムに存在する場合は、そのクラスローダが返されます。 存在しない場合は、新しいクラスローダが作成されます。コードベースがnullである場合、そのコードベースはloadClass(String)メソッドによりクラスをロードするのに使用するクラスローダを返します。コードベースパラメータがnullではない不正な URL を含んでいる場合、このメソッドはMalformedURLExceptionをスローします。 また、呼び出し側にコードベース URL パス内のすべての URL に接続するためのアクセス権がない場合は、SecurityExceptionをスローします。
getSecurityContextメソッドは、JDK 1.1 でクラスローダベースのセキュリティチェックを実装するために内部で使用されていましたが、Java 2 プラットフォームのセキュリティモデルには適用されなくなったため、現在では推奨されません。RMIClassLoader.loadClassメソッドの 1 つを呼び出すサービスを提供するために、指定されたクラスローダが RMI ランタイムによって作成された場合は、クラスローダのコードパス内の最初の URL が返されます。 それ以外の場合は、nullが返されます。3 つの
loadClassメソッドは、どれも現在のスレッドのコンテキストクラスローダを使って、指定された名前を持つクラスをロードしようとします。 セキュリティマネージャのセットがある場合は、特定のコードベースパスの内部URLClassLoader(メソッドによって異なる) が使われます。
- クラス name というパラメータを 1 つだけとる
loadClassメソッドは、java.rmi.server.codebaseプロパティの値を、使用するコードベースパスとして暗黙に使います。このjava.rmi.server.codebaseプロパティの使用が推奨されないため、このバージョンのloadClassメソッドの使用は推奨されません。 次のより一般的なバージョンを使ってください。Stringcodebase パラメータをとるloadClassメソッドは、そのパラメータをコードベースパスとして使います。 コードベース文字列は、getClassAnnotationメソッドにより返される文字列のように、スペースで区切られた URL リストである必要があります。java.net.URLcodebase パラメータをとるloadClassメソッドは、その単一のURLをコードベースとして使います。
どのloadClassメソッドについても、現在のスレッド上でgetContextClassLoaderを呼び出すことによって決定される現在のスレッドのコンテキストクラスローダとコードベースパスを使って、クラスのロード元とする内部クラスローダのインスタンスが決定されます。RMI ランタイムは、親クラスローダとローダのコードベースパス (順序付けられた URL リスト) で構成されるペアがキーとなる内部クラスローダのインスタンスのテーブルを保持します。loadClassメソッドは、目的のコードベースパスと、現在のスレッドのコンテキストクラスローダを親として持つURLClassLoaderのインスタンスを検索します。そのようなローダが存在しない場合は、作成されてテーブルに追加されます。最後に、指定されたクラス名を使って、選択されたクラスローダ上でloadClassメソッドが呼び出されます。セキュリティマネージャのセットがある (
System.getSecurityManagerがnullを返さない) 場合は、loadClassの呼び出し側に、コードベースパス内のすべての URL に接続可能なアクセス権が必要です。 そのようなアクセス権がない場合は、ClassNotFoundExceptionがスローされます。セキュリティマネージャがない JVM に信頼のおけない任意のコードがロードされることを防ぐため、セキュリティマネージャのセットがない場合は、どのloadClassメソッドも特定のコードベースパスを無視し、現在のスレッドのコンテキストクラスローダから指定された「名前」を持つクラスだけをロードしようとします。