我已经关注了这个RMI业务的一系列教程,以了解如何正确地做到这一点。 Oracle的教程使用了SecurityManager
,而其他大多数人并不烦恼。一些扩展UnicastRemoteObject
,而其他exportObject
。有些人从外部和RMIRegistry
运行getRegistry
,而其他人createRegistry
。
现在,我认为在我面前挑选出那些选项对我来说是有益的,所以这就是我所做的:
首先,我已经去了安检,因为为什么不呢?
其次,我不喜欢扩展UnicastRemoteObject
,因为我的对象并不完全是远程的,只是有一些远程方法。例如,在我的构造函数中有一个throws RemoteException
子句似乎并不合适。
最后,我不想从外部运行注册表,因为我不是真正运行服务器,它只是一个应用程序。此外,我不想让两个/三个单独的地方为注册表设置端口。
这里是我的服务器代码,(希望)做我已经描述过的事情:
package server;
import interf.TicTacToeBoard;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TicTacToeServer
{
private static Registry registry;
public static void main(String[] args)
throws RemoteException, AlreadyBoundException
{
System.out.println("Server is up!");
System.setProperty("java.security.policy", "file:/<policy_file_path>");
if (System.getSecurityManager() == null)
System.setSecurityManager(new SecurityManager());
TicTacToeBoardImpl arena = new TicTacToeBoardImpl();
TicTacToeBoard stub =
(TicTacToeBoard) UnicastRemoteObject.exportObject(arena, 0);
registry = LocateRegistry.createRegistry(TicTacToeBoard.RMI_PORT);
registry.bind(TicTacToeBoard.RMI_NAME, stub);
System.out.println("Waiting for connections.");
}
}
这件事情还没有完成;但就能够服务远程对象而言,它应该是。但是,在使用"Waiting for connections."
打印该行之后,应用程序才会静默终止。
我对此的唯一解释是应用程序被垃圾收集。
在Oracle的示例中,它不会收集垃圾,因为在那里,RMIRegistry作为服务器应用程序的单独应用程序运行,而RMIRegistry应用程序保存对驻留在服务器应用程序内的对象的引用。
我执行extends UnicastRemoteObject
时没有收集垃圾,因为......我不知道。我所知道的是应用程序然后继续运行。
如果我在任何阶段出错,请纠正我。最重要的是,我的问题是,我的选项是什么,不涉及将RMIRegistry作为一个单独的流程运行,并使我的实现扩展UnicastRemoteObject
?
答案 0 :(得分:0)
这不应该发生。 1 两个远程对象的存在应该使端口监听线程保持运行,静态变量应该保持注册表对象的存在。尝试制作实现和存根静态字段,如注册表。
我已经去了安检,因为为什么不呢?
但为什么呢?除非你要运行不受信任的代码,或者在其他人的计算机上运行,否则这只是一种痛苦。
1:确实不会发生在我身上。它一直在运行。您确定Registry
引用确实是static
吗?