转载自: 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 配置代码,如下:
RMI问题2:
RMI 服务器重启,总是会出现客户端连接拒绝的问题。
分析:
服务器重启会影响到客户端,说明客户端有保存着重启之前的服务器连接相关记录。经研究发现,客户端有缓存,所以只要刷新缓存即可解决问题。
解决:
在客户端连接代码中增加代码:
RMI问题3:
Spring RMI会占用两个端口?
分析:
Spring RMI 有两个端口,一个是注册端口(默认为1099),还有一个是数据传输端口,如果不指定,数据传输端口是随机分配的。
解决:
在xml配置时,配置servicePort
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服务器重启导致客户端连接失败的原因,并提供了两种解决方案:使用RmiRegistryFactoryBean正确关闭RMIRegistry,或者在客户端连接代码中设置lookupStubOnStartup和refreshStubOnConnectFailure属性,以避免缓存旧连接信息,从而解决重启服务器后的连接问题。
1634

被折叠的 条评论
为什么被折叠?



