環境
これは Java RMI を使用するアプリケーションで、次のものがあります。
- ホスト A 上のクライアントとホスト B 上のサーバー。
- ホスト A 上の HTTP サーバー。クライアントとサーバーが使用するすべてのクラスのコピーを保持します。
- RMI レジストリはサーバー コードから作成され、サーバー JVM と CLASSPATH を共有します。
サーバーおよびクライアント アプリケーションの場合:
java.rmi.server.codebase
プロパティは (コード内で) HTTP サーバーの URL に設定されます。- 適切なポリシーを備えたセキュリティ マネージャーが配置されています。
- は
java.rmi.server.hostname
LAN アドレスに設定されます。
メソッド呼び出し:
- サーバー メソッドは、型
WorkRequest
(抽象クラス) のパラメーターで定義されます。 - クライアントは、サブクラスを使用してこのメソッドを呼び出します
WorkRequestSquare
。 WorkRequestSquare
サーバーコードでは決して言及されていません
サーバーコード
Object execute(WorkRequest work) throws RemoteException { return work.execute(); }
クライアントコード:
try { servant.execute(new WorkRequestSquare(123)); }
catch (RemoteException e) {
System.out.println("Error while submitting work request:");
e.printStackTrace();
}
このコードは、サーバーの CLASSPATH にすべての関連クラスがあり、動的ロードが必要ない場合に機能します。
問題
サーバー側で CLASSPATH から削除WorkRequestSquare
すると、クライアント側で例外がスローされます (サーバー側では何もスローされません)。
Error while submitting work request:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: WorkRequestSquare
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
...
WorkRequestSquare
サーバーコードで明示的に言及されていないため、動的にロードできるはずですが、そうはなりません。
バイパス
Stuart Marks から、プロパティjava.rmi.server.useCodebaseOnly
を に設定する必要があることがわかりましたfalse
。
このプロパティのデフォルト値は、JDK 7u21 でfalse
からに変更されました。を使用してローカルに定義された場所を除いて、JVM が任意の場所からクラスを動的にロードするのを防ぐために設定します。これは、パラメーターをマーシャリングするときにクライアント JVM によって設定されたコードベース値が、サーバーによって無視されることを意味します。true
useCodebaseOnly
true
java.rmi.server.codebase
WorkRequestSquare
useCodebaseOnly
true
サーバーで がにuseCodebaseOnly
設定さfalse
れ、WorkRequestSquare
クラスがサーバーの CLASSPATH から削除されると、サーバーは HTTP サーバーからクラス定義を取得するようになりました。これは有効なバイパスです。
質問
クライアントとサーバーのプロパティの値が同じであるため、まだ何か異常がありcodebase
ます。
useCodebaseOnly
サーバーにデフォルト設定された場合true
、JVM は RMI ストリームに追加されたクライアントを無視する必要がありましたが、クラスを取得するためにcodebase
独自のものを使用する必要がありました。codebase
WorkRequestSquare
codebase
クライアントとサーバーの値が同じであるため、これはとにかく成功するはずです。
誰かがその問題に光を当てることができますか?