java - LocateRegistry.createRegistry() 不能使应用程序保持 Activity 状态

标签 java rmi program-entry-point rmiregistry remote-registry

我已经用 ruby​​duck 调试了每一行代码以及多个工作示例,但由于某种原因,当我启动 RMI 服务器时,我的 java 应用程序就关闭了。

我希望 java 应用程序继续运行,因为我已经启动了注册表,并且已经重新绑定(bind)了一个实现 java.rmi.Remote 的对象。

但是发生的情况是应用程序在创建完所有内容后立即停止。

这是我的 Main.java:

package com.distribridge.servercomponent;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

    private static Logger logger = Logger.getLogger(Main.class.getName());
    private static int portNumber = 1099;

    private Main() {
        logger.log(Level.INFO, "Starting component");

        Server server;
        try {

            server = new Server();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not create server.");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Server created.");

        Registry registry;
        try {
            registry = LocateRegistry.createRegistry(portNumber);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not create registry");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Registry created.");

        try {
            registry.rebind("server", server);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Could not bind server.");
            System.exit(1);
            return;
        }

        logger.log(Level.FINE, "Server bound.");
        logger.log(Level.INFO, "Component started.");
    }

    public static void main(String[] args) {
        System.out.println("Start");
        Main main = new Main();
    }
}

我的 Server.java 看起来像这样:

public class Server implements IServerForClientLogin, IServerForClient, IServerForTable, Remote {
    Server() {
        System.out.println("Server Constructor");
    }

    //Some methods that don't get called yet.
}

服务器扩展的接口(interface)位于“共享”模块中。我使用该模块启动了该项目,并添加了服务器等模块。

这是我的控制台输出:

Start 
Jan 03, 2018 1:10:05 PM com.distribridge.servercomponent.Main <init>
INFO: Starting component
Server Constructor 
Jan 03, 2018 1:10:05 PM com.distribridge.servercomponent.Main <init>
INFO: Component started.

Process finished with exit code 0

如您所见,当注册表绑定(bind)了远程对象时,进程立即关闭。

最佳答案

用于存储 LocateRegistry.createRegistry() 结果的 Registry 需要是静态的。

否则它可能会被垃圾收集,从而取消导出它,从而允许其中的所有 stub 进行 GC,从而允许它们引用的远程对象进行 DGC,从而取消导出它们,从而允许 RMI接受线程退出,从而允许 JVM 退出。

但是你还有另一个问题。您的Server还不是远程对象。您需要通过扩展 UnicastRemoteObject 或调用 UnicastRemoteObject.exportObject() 来导出它。目前它只是一个移动代理,直接运送到客户端并在那里执行。

Server不需要直接实现Remote。它需要实现扩展远程的接口(interface)。

关于java - LocateRegistry.createRegistry() 不能使应用程序保持 Activity 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48077243/

相关文章:

java - 在java中将字体的字符宽度设置为统一

java - 使用服务帐号列出 G Suite 上的云端硬盘文件时未经授权

java - RMI - 使用 rmic 创建 stub

java - 如果 main 方法在 java 文件的 "non public class"中怎么办?

java - Maven 错误 : Could not find or load main class

java - 有关创建只读 Android 应用程序的两部分查询

java - 了解 Android 中的 Runnable

java - 线程中出现异常 "main"java.rmi.NotBoundException

java rmi服务器端异常处理

java - 使用基于对象的 run() 方法而不是静态 main 有什么优势吗?