15

Java RMI クライアント/サーバー アプリを作成しようとしています。アプリのサーバー側を起動しようとすると、Registry.bind() メソッドの呼び出し中にClassNotFoundExceptionが発生し続けるため、アプリのサーバー側を起動するときに問題が発生します。

ここの簡単なチュートリアルから始めました: http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html。これらの指示に従った後、最初は「example.hello.Hello」が見つからないことを訴える ClassNotFoundException をスローしていました。rmir​​egistryはどうやらクラスパスの一部として最初の開始ディレクトリを使用するため、チュートリアルのdestDirディレクトリからrmiregistry を開始することで解決できました。

その後、別のテスト アプリを使い始めましたが、サーバー クラスでサードパーティの jar ファイルを使い始めるまでは問題ありませんでした。現在、rmiregistry アプリはこれらの jar ファイルを認識していないため、私のサーバー クラスが任意の jar ファイル内の何かを参照している場合、Registry.bind() は ClassNotFoundException をスローします。

私が知る限り、rmiregistry はクラスパスの起動引数を一切受け入れないので、認識させたいクラスパスをどのように伝えることができるのか疑問に思っています。http://docs.oracle.com/javase/tutorial/rmi/running.htmlのチュートリアルによると、「rmiregistry を実行するシェルまたはウィンドウにCLASSPATH 環境変数が設定されていないか、リモート オブジェクトのクライアントにダウンロードするクラスへのパスを含まない CLASSPATH 環境変数があります。」それは私が必要としているものとは正反対のように聞こえます... それとも私の読み方が間違っているのでしょうか? サードパーティの jar (私の場合は commons-io、commons-logging、および rmiio) を使用する RMI クライアント/サーバーの起動に成功した人はいますか?

ちなみに、これはWindows上です。


更新 私はそれを回避する方法を見つけました。以下の私の答えを見てください。

4

4 に答える 4

5

CLASSPATH の設定解除に関する注意事項は、RMI コードベース機能を使用している場合にのみ適用されます。これは、クラスのダウンロードに関する不可解な注意事項が暗示することを意図しているためです。

コードベース機能を使用していない場合は、次のいずれかを行ってください。

  1. rmiregistry,ここに示されているように、開始する前に必要に応じて CLASSPATH 環境変数を設定するか、
  2. rmiregistryから始める-J-Djava.class.path=...
  3. サーバー JVM 内でレジストリを起動します。LocateRegistry.createRegistry().これは多くの点で最良のソリューションです。JVM と一緒に生きて死に、クラスパスを共有し、コードベース機能の要件にも付随的に準拠しているためです。

(3) を行う場合は、戻り値を静的変数に格納して、ガベージ コレクションが行われないようにする必要があります。これにより、レジストリがアンエクスポートされ、リモート オブジェクトの DGC が発生する可能性があります。 GC を実行すると、リスニング スレッドが終了し、JVM 全体が終了する可能性があります。

于 2014-05-14T00:26:11.083 に答える
4

(私はもともと、この回答を質問の更新として投稿していました。コメントの 1 つにある Zecas の提案に従って、回答セクションに移動しています。)

上記の質問で参照されている 2 番目のチュートリアルの提案に従わないことで、サーバー部分を起動することができました。

「rmiregistry を実行するシェルまたはウィンドウに、CLASSPATH 環境変数が設定されていないか、リモート オブジェクトのクライアントにダウンロードするクラスへのパスが含まれていない CLASSPATH 環境変数があることを確認する必要があります。

CLASSPATH 環境変数を作成し、.class 出力ディレクトリと各サードパーティの jar ファイルをそこに追加しました。以前に試したことがあると思いましたが、そうではないと思います...他の誰かが同じ問題を抱えている場合に備えて、解決策を残しておくと思いました。

于 2013-12-02T20:40:34.493 に答える
4

RMI レジストリ固有の Java クラス パスはありません。Java システムの残りの部分と同じクラスパスを使用する必要があります。コマンドラインまたはOS環境で指定することにより、クラスパスを設定できます。少し古くなっていますが、このドキュメントは正しい方向性を示しているはずです。

于 2012-12-11T22:09:05.273 に答える
1

rmir​​egistry のクラスパスを設定する方法の例

Win32:

set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar 

UNIX:

setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar
于 2014-05-13T23:02:38.690 に答える