【问题标题】:Stopping RMI Server (Java)停止 RMI 服务器 (Java)
【发布时间】:2016-01-21 21:43:28
【问题描述】:

我创建了一个成功的 RMI 服务器,感谢上帝 :)

完美运行.. 我有一个 JForm,点击一个按钮就会激活它。

虽然我也想创建一个按钮来停用它,但我在取消导出它时遇到了问题。

好的,这就是我尝试导出和终止 RMI 服务器的方式

private void btStopServerActionPerformed(java.awt.event.ActionEvent evt) {
 try {
            // Nome do objecto
            String objectname = txtObjectName.getText();
            // obtem o número da porta
            int port = Integer.parseInt(txtServerPort.getText());

            RemoteMessageObject remote = new RemoteMessageObject();
            Registry registry = LocateRegistry.getRegistry(port);
            UnicastRemoteObject.unexportObject(LocateRegistry.getRegistry(port), true);
            registry.unbind(objectname);


            System.out.println("Server offline");
        } catch (IOException ex) {
            Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotBoundException ex) {
            Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }       

我得到了这个例外:

java.rmi.NoSuchObjectException: object not exported

在线:

UnicastRemoteObject.unexportObject(LocateRegistry.getRegistry(port), true);

我在这里做错了什么?

已解决........

我之前发现了它:P 无论如何感谢@EJP 的正确答案。

所以我的解决方案是在类作为公共变量启动时创建 Register,这样它就可以在两个点击事件中使用(启动服务器和停止服务器)。

我删除了太多废话,就像@EJP 所说的那样,禁用 RMI 服务器不是必需的。

它现在是这样工作的:

private void btStopServerActionPerformed(java.awt.event.ActionEvent evt) {                                             

    try {
        // Nome do objecto
        String objectname = txtObjectName.getText();
        // obtem o número da porta
        int port = Integer.parseInt(txtServerPort.getText());

        Registry registry = LocateRegistry.getRegistry(port);
        UnicastRemoteObject.unexportObject(this.registry, true);
        registry.unbind(objectname);

        System.out.println("Server offline");
    } catch (IOException ex) {
        GuiUtils.addText(txtLog, "Erro", "Servidor desligado");
        btStopServer.setEnabled(false);
        btStartServer.setEnabled(true);
    } catch (NotBoundException ex) {
        Logger.getLogger(ServerGUI.class.getName()).log(Level.SEVERE, null, ex);
    }
}      

【问题讨论】:

  • 定义“问题”。例外?堆栈跟踪?什么都没发生?
  • @Marvin java.rmi.NoSuchObjectException:对象未在以下行导出:“UnicastRemoteObject.unexportObject(LocateRegistry.getRegistry(port), true);”
  • 仍然还没有取消导出你自己的远程对象,这是整个问题的重点。如果客户端已经拥有来自先前lookup(). 的存根,则客户端仍然可以调用它。因此,“服务器脱机”的消息是错误的。 NB 在你的新代码中调用getRegistry() 是没有意义的,如果你成功取消导出注册表,则根本不需要调用unbind()
  • @EJP 你是救命稻草,事实上,解除绑定和我拥有的所有代码确实阻止了更多人登录远程连接。尽管如此,就像你说的那样,已经登录的人,即使服务器离线,他们仍然可以使用远程方法。非常感谢。我现在有几个错误,但我会尝试自己修复它。我稍后会更新主要帖子,以免传播错误信息。
  • 声称他们无法登录是不正确的。如果他们已经有存根,他们可以调用任何方法。解除绑定毫无意义,因为注册表已不复存在。您所要做的就是取消导出注册表和对象。

标签: java rmi


【解决方案1】:

您需要取消导出LocateRegistry.createRegistry(). 返回的对象getRegistry() 返回的对象不是实际的Registry 对象,它是一个存根,您无法取消导出这些对象。

但是取消导出注册表然后调用unbind() 没有意义。反过来说有点道理,但意义不大。

而且您还必须取消导出您自己的远程对象。

并且在试图取消导出现有对象的方法中创建一个新的远程对象也没有任何意义。

【讨论】:

    猜你喜欢
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 2015-07-04
    • 1970-01-01
    • 2011-02-17
    相关资源
    最近更新 更多