0

この投稿はできるだけ小さくして、リクエストがあれば情報とコードを追加します。

シナリオ: 私は、社内のプロセスの一部を追跡するサーバー/クライアント アプリケーションを作成しているため、ユーザーは、ワークフローに従って、あるユーザーの画面から別のユーザー (Swing で作成されたクライアント) に移動する小さなタグを作成します。

ローカルの Glasfish 3.1 サーバー (Eclipse) と MySql を実行しています。サーバーでは、Spring MVC と Spring Data + Hibernate を実行しています。

プロパティ ファイルには、簡単に変更できるように次の情報が保持されます。

rmi.serverPort = 1971
rmi.clientPort = 2010

サーバーの起動時に、RMI 環境を次のように設定する Bean があります。

  @Autowired
  private RmiData rmiData;
  @Autowired
  private DataRequestHandler dataRequestHandler;
  @Autowired
  private ConnectionRequestHandler connectionRequestHandler;
  .
  .
  .

  LocateRegistry.createRegistry(rmiData.getServerPort());
  String rmiUrl = "rmi://" + rmiData.getHost() + ":" + rmiData.getServerPort() + "/";
  Naming.rebind(rmiUrl + "ConnectionRequestHandler", connectionRequestHandler);
  Naming.rebind(rmiUrl + "DataRequestHandler", dataRequestHandler);

サーバーには両方のハンドラーのインターフェースと実装が含まれ、クライアントにはインターフェースのみがあります。

これは、SecurityManager と Policy ファイルなしで機能しています。他の例外を解決するために、Hibernate jar をクライアントに含める必要がありましたが (解決策は SO でここにあります)。

サーバーに接続してデータを要求するクライアントを作成した後、クライアントへのコールバックのコーディングを開始しました (サーバーはクライアントにもデータをプッシュする必要があります)。これが私が今立ち往生しているところです。

コールバックを作成する方法は次のとおりです (クライアントはサーバーのように機能します)。

  private ClientCallbackHandler clientCallbackHandler = new ClientCallbackHandlerImpl();
  .
  .
  .

  LocateRegistry.createRegistry(rmiData.getClientPort());
  String rmiUrl = "rmi://localhost:" + rmiData.getClientPort() + "/";
  Naming.rebind(rmiUrl + "ClientCallbackHandler", clientCallbackHandler);

サーバーにはクライアント インターフェースのみが含まれ、クライアントにはハンドラーのインターフェースと実装の両方があります。

したがって、サーバーが実行するとき

  String rmiUrl = "rmi://" + clientHost + ":" + clientPort + "/";
  clientCallbackHandler = (ClientCallbackHandler)Naming.lookup(rmiUrl + "ClientCallbackHandler");

サーバーで次の例外が発生します。

  SEVERE: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: br.com.affair.socontrol.rmi.ClientCallbackHandlerImpl (no security manager: RMI class loader disabled)

SecurityManager と Policy ファイルのインストールを避けています (これも試してみましたが成功しませんでした)、ここで立ち往生しています。

必要なのはインターフェースだけなのに、サーバーが実装クラスについて不平を言っている理由がわかりません。どんな助けでも大歓迎です。ありがとう。

4

1 に答える 1

1

これに数時間苦労した後、ようやく問題が見つかりました。

ClientCallbackHandlerImpl クラスはUnicastRemoteObjectを拡張していません でした。その後、コードはスムーズに実行されました。投稿を読んで何か考えてくれてありがとう。

PS:初心者のせいだと思いますが、コードのコピー/貼り付けは避けています。

于 2013-03-06T15:02:24.827 に答える