Spring RMI注意问题

转载自: http://yangwencan2002.iteye.com/blog/284249

RMI问题1:
用 ./shutdown.sh 关闭 rmi 服务器的 tomcat ,然后 ./startup.sh 启动,客户端连接总是会导致如下错误:
org.springframework.remoting.RemoteLookupFailureException: Lookup of RMI stub failed; nested exception is java.rmi.UnmarshalException: error unmarshalling return; nested exception is:  
    java.io.EOFException

分析:
The cause of the problem is the fact that Spring creates an RMIRegistry with the classloader of the server webapp. Then, when restarting the server, the RMIRegistry is not shut down. After the restart the Registry keeps its references to the old Stubs which do not exist anymore.
There are two solutions:
   1) Start the rmiregistry in a seperate process without the classpath of the server app.
   2) (better approach) Let spring start the RMIRegistry throu RmiRegistryFactoryBean, which shuts it down correctly.

解决:
将服务器中的 spring 配置代码,如下:
<bean id = "rmiService" class = "org.springframework.remoting.rmi.RmiServiceExporter" >
    <property name = "serviceName" value = "service1" />
    <property name = "service" ref = "servicebean" />
    <property name = "serviceInterface" value = "com.Iservice" />
    <property name = "registryPort" value = "1099" />
</bean >
替换为:
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
    <property name="port" value="1099"/>
</bean>
<bean id = "rmiService" class = "org.springframework.remoting.rmi.RmiServiceExporter" >
    <property name = "serviceName" value = "service1" />
    <property name = "service" ref = "servicebean" />
    <property name = "serviceInterface" value = "com.Iservice" />
    <property name="registry" ref="registry"/>
</bean >


RMI问题2:
RMI 服务器重启,总是会出现客户端连接拒绝的问题。

分析:
服务器重启会影响到客户端,说明客户端有保存着重启之前的服务器连接相关记录。经研究发现,客户端有缓存,所以只要刷新缓存即可解决问题。

解决:
在客户端连接代码中增加代码:
RmiProxyFactoryBean factory= new RmiProxyFactoryBean();
factory.setServiceInterface(IService. class );
factory.setServiceUrl(url);

//解决重启 rmi 的服务器后会出现拒绝连接或找不到服务对象的错误
factory.setLookupStubOnStartup(false);//不在容器启动的时候创建与Server端的连接
factory.setRefreshStubOnConnectFailure(true);//表示是否连接出错时自动重连

factory.afterPropertiesSet();
IService service=( IService)factory.getObject();


RMI问题3:
   Spring RMI会占用两个端口?

分析:
Spring RMI 有两个端口,一个是注册端口(默认为1099),还有一个是数据传输端口,如果不指定,数据传输端口是随机分配的。

解决:
在xml配置时,配置servicePort
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
    <property name="port" value="1099"/>
</bean>
<bean id = "rmiService" class = "org.springframework.remoting.rmi.RmiServiceExporter" >
    <property name = "serviceName" value = "service1" />
    <property name = "service" ref = "servicebean" />
    <property name = "serviceInterface" value = "com.Iservice" />
    <property name="registry" ref="registry"/>
    <property name="servicePort" value="1199" />
</bean >









你可能感兴趣的:(Spring RMI注意问题)