Java RMI 服务器作为守护进程运行,客户端连接被拒绝

标签 java rmi jobs

如果我将 Java RMI 服务器作为守护进程运行(末尾带有 &),似乎它总是自动停止

这是启动 RMI 服务器的命令

java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-   bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi &

这是打印输出:

user@agent033:~/remoteconfig> java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi &
[3] 7437
Remote Object bind at (RMI): //10.***.***.***3002/RemoteConfigure
Remote Object: RemoteServiceImpl[UnicastServerRef [liveRef: [endpoint:[10.***.***.***:3003](local),objID:[3412cf8e:147646da428:-7fff, 7055633182216564676]]]]

Here I input a carriage return

[3]+  Stopped                 java -Djava.security.policy=java.policy -cp .:lib/mysql-connector-java-5.1.7-bin.jar:lib/jsch-0.1.44.jar com.company.remote.server.rmi.RemoteServiceRmi

如果我不输入回车符,则不会显示“已停止”行。客户端仍然无法与服务器通信。客户将得到:

error during JRMP connection establishment; nested exception is:
java.net.SocketTimeoutException: Read timed out

如果我删除命令末尾的“&”,服务器可以成功启动,并且客户端可以毫无问题地与服务器通信。

以下是服务器端RMI初始化的代码:

private void initializeRmiService() throws RemoteException, MalformedURLException {
    int registryPort = Integer.parseInt(PropertyHandler.getProperty("rmi_regport"));
    String connectionPort = PropertyHandler.getProperty("rmi_connport");
    String rmiNamingUrl = "";

    RemoteServiceInterface agent = new RemoteServiceImpl(Integer.parseInt(connectionPort));
    rmiNamingUrl = "//" + PropertyHandler.getProperty("rmi_hostaddress") + ":" + registryPort + "/" + PropertyHandler.getProperty("rmi_naming");
    logger.info("Remote Object bind at (RMI): " + rmiNamingUrl);
    if (System.getSecurityManager() == null) {
        System.setSecurityManager(new SecurityManager());
    }
    LocateRegistry.createRegistry(registryPort);
    Naming.rebind(rmiNamingUrl, agent);
    logger.info("Remote Object: " + agent);
}

最佳答案

当您从 shell 运行某些内容并提供 & 后缀时,它会在后台运行。

这个问题与 RMI 关系不大,可能与尝试从终端读取数据的后台进程有关。在大多数类 Unix 系统上,如果后台进程尝试从终端读取(通常但不总是其标准输入),操作系统将自动停止该进程。原因是,由于该进程位于后台,因此前台可能有其他进程从终端读取数据。如果两个进程同时从终端读取数据,进程的输入将以不可预测的方式交错,这将是很糟糕的。

参见this answer了解更多信息。

我敢打赌,您的 RMI 服务器中的某处有从 System.in 读取的代码。把它拿出来,你的进程应该在后台运行良好。 RMI 的问题是您的进程被操作系统停止,因此连接请求超时。如果您避免从终端读取,该过程将不会在后台停止。在后台运行时监听套接字和接受 RMI 连接应该没有问题。

关于Java RMI 服务器作为守护进程运行,客户端连接被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24918323/

相关文章:

java - 如何在 rest web 服务 java 上注入(inject)应用程序范围 bean

java - rmir​​egistry 或 JNDI 是否以序列化形式存储对象

java - 执行字符串作为方法?

java - Quartz 作业未启动 - Tomcat 服务器

sql-server - 为什么我的 SSIS 包完成时出现错误,而看似没有错误?

java - 在 XPath 中,如何选择与子集不匹配的所有节点?

java - 在 1 次迭代中从未排序的数组列表生成排序的数组列表?

java - 在类中创建新的 KeyListener 时出现问题

Java:套接字还是 RMI?

php - *Job Class* 和 Illuminate\Bus\Queueable 在 *Job Class* 的组合中定义了相同的属性 ($connection)