2

私は以前、明確に定義されたクライアント/サーバー関係があった多くのプロジェクトでRMI(Java 6)を正常に使用しました。以前のプロジェクトで使用していたときに、クライアントとサーバーの両方にデプロイされる明確に定義されたインターフェイスJARを作成し、「-Djava.rmi.server.codebase =...-Djava」を使用してRMIサーバーを起動しました。 .rmi.server.hostname = localhost -Djava.security.policy = ... \ server.policy "

基本的なクラスターを構築するために、RMIを使用して双方向通信を実行しようとしています。具体的には、B(ワーカー「クライアント」)をA(中央「サーバー」)に登録してほしい。ただし、Bにjava.rmi.Remoteインターフェースを実装し、自分自身の参照をAに戻すようにします。これの主な動機は次のとおりです。* Aは、Bのすべてのインスタンスがどこにあるかを知る必要はありません(インターネット上のどこでも、必要に応じて!)* BのインスタンスがAに登録されると、AはBを制御できます(つまり、Aの裁量でBに対してタスクを実行します)。

私の問題は、このリモートインターフェイス(B)をパラメータとしてAに戻そうとすると、Bで次の例外が発生することです(ただし、代わりにnullを渡すと、リモート呼び出しが正常に発生するため、この説明はありそうにありません:http ://download.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html#section6):

ERROR com.mycompany.server.dao.ServerInterfaceImpl - RMI registerWorker() failed: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.mycompany.worker.MyWorker (no security manager: RMI class loader disabled)

ここで、* A(実装)= com.mycompany.server.dao.ServerInterfaceImpl * B = com.mycompany.worker.MyWorker

(Q1)私が説明していることを行うことは可能ですか?誰かが私が説明しているものの超基本バージョンを書くことができますか(つまり、クライアントBはサーバーAに登録し、AがBを制御できるようにBのリモートインターフェイスへの参照をAに渡します)?私は当初、いくつかのあいまいなタイプミス/構成の問題があると思っていましたが、このタスクを開始することはできません...

(Q2)私がやろうとしていることが不可能な場合、別のアイデアは、Bの各インスタンスをRMIサーバーに変え、BがAに接続した後にAをBに接続させることです。私が望まない主な理由これを行うには、Aと(の各インスタンス)Bがインターネットによって分離され、Aのみがパブリックインターネットアドレスを持っていると予想します(Bの各インスタンスはパブリックIPアドレスを持たず、さまざまな背後にスタックする可能性があります)ファイアウォール。BがAに接続するのはその逆よりも簡単です)...結局のところ、BがAに接続したら、双方向通信を促進したいだけです。

(Q3)AとBの間にハートビートを設定することを検討していました。1つの可能性として、各Bにこれらのハートビートを使用して、未処理の作業でAをポーリングすることが考えられます。

4

1 に答える 1

0

java.lang.ClassNotFoundException: com.mycompany.worker.MyWorker

これは、クラスをデシリアライズしようとしたノードにそのクラスが存在しないことを意味します。だからそこに置いてください。

ファイアウォールが許可していれば、あなたが試みていることは機能します。インターネットが関係している場合は、基本的に忘れることができます。

于 2011-08-17T08:19:54.780 に答える