在创建RMI服务时,需要将该服务通过JNDI绑定到特定的端口上。
开RMI服务端口的一般方法是:
RMIEngine pt = new RMIEngineImpl();
int port =1099;
String serviceName = "MyRMIService"
try {
LocateRegistry.createRegistry(port);
LocateRegistry.getRegistry();
} catch (Exception ex) {
logger.error(ex);
throw ex;
}
Registry registry = LocateRegistry.getRegistry(port);
registry.bind(serviceName, pt);
当该端口已经被占用时,会抛出"ObjID already in use" 或者 "Port already in use" 的异常。
但在RMI服务的处理上,有些问题一直很难妥善处理,主要为以下几个:
1、在JDK1.4上,同一个JVM中只能开一个端口,开第二个端口时,会出现"ObjID already in use"的异常,经查证,所有的register的ObjID都为“"0.0.0.0",所以会导致该异常出现。而在JDK1.5上没有该问题。
2、一直没有找到能够正确的关闭端口的方法。
一般的方法是:
//取消服务绑定
registry.unbind(serviceName);
//注销端口占用
UnicastRemoteObject.unexportObject(registry, true);
或者 PortableRemoteObject.unexportObject(registry);
该方式在同一个线程内可以重复的开关同一个端口,但在不同的线程中时,好像仍然不能有效地关闭该端口,再打开时仍然会报端口被占用的异常。
所以:当在应用服务器中重启一个带有rmi服务的应用时,经常会碰到端口被占用的问题。而独立的JVM启动一个rmi服务则没有问题。
3、两个Registry对象的区别 (不是问题)
Registry registry = LocateRegistry.createRegistry(port); //此时为local端的register
Registry registry2 = LocateRegistry.getRegistry(); //此时为remote端的register
这两者是不同的,在注销端口是好像是要传入local端的register才可以。
4、stub类的生成问题,目前来说服务端和客户端的stub类好像是必须一致才可以正常访问,若两端不一致,容易产生传值错误。对于升级或者产品开发方面需要特别注意。
不知道这些问题,有没有人完美的解决过?