`
yangwencan2002
  • 浏览: 37145 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

RMI@Spring的常见问题解决

    博客分类:
  • Java
阅读更多

<!----><!----><!---->

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

com.ffcs.ieie.communicate.ieiemp.IeiempException: org.springframework.remoting.RemoteLookupFailureException: Lookup of RMI st

ub failed; nested exception is java.rmi.UnmarshalException: error unmarshalling return; nested exception is:

        java.io.EOFException

RMI 问题 1 分析:

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.

参考: http://forum.springframework.org/showthread.php?t=33073

RMI 问题 1 解决:

将服务器中的 spring 配置代码,如下:

    < bean id = "incomingService" class = "com.ffcs.ieiemp.ieie.rmi.IncomingService" />

    < bean id = "rmiService" class = "org.springframework.remoting.rmi.RmiServiceExporter" >

        < property name = "serviceName" value = "IncomingService" />

        < property name = "service" ref = "incomingService" />

        < property name = "serviceInterface" value = "com.ffcs.ieiemp.ieie.rmi.Incoming" />

        < property name = "registryPort" value = "1099" />

</ bean >

替换为:

    <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">

       <property name="port" value="1099"/>

    </bean>

    < bean id = "incomingService" class = "com.ffcs.ieiemp.ieie.rmi.IncomingService" />

    < bean id = "rmiService" class = "org.springframework.remoting.rmi.RmiServiceExporter" >

        < property name = "serviceName" value = "IncomingService" />

        < property name = "service" ref = "incomingService" />

        < property name = "serviceInterface" value = "com.ffcs.ieiemp.ieie.rmi.Incoming" />

        <!-- <property name="registryPort" value="1099"/> -->

        <property name="registry" ref="registry"/>

</ bean >

 

RMI 问题 2 背景:

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

RMI 问题 2 分析:

          服务器重启会影响到客户端?说明客户端有保存着重启之前的服务器连接相关记录。经研究发现,客户端 Stub 有缓存,所以只要刷新缓存即可解决问题。参考: http://forum.springsource.org/showthread.php?t=61575

RMI 问题 2 解决:

          在客户端连接代码中增加红色标识的代码:

       RmiProxyFactoryBean factory= new RmiProxyFactoryBean();

       factory.setServiceInterface(Incoming. class );

       factory.setServiceUrl(url);

       // XXX vincan: 解决重启 rmi 的服务器后会出现拒绝连接或找不到服务对象的错误

       factory.setLookupStubOnStartup(false );

       factory.setRefreshStubOnConnectFailure(true );

       factory.afterPropertiesSet();

    Incoming service=(Incoming)factory.getObject();

 

RMI 问题 3 背景:

          两台服务器, JDK 都是 1.6 ,在一个局域网内,内网 IP 分别为 192.168.39.11 192.168.39.164 ,对应的的还有外网 IP 。写了一个 RMI 服务器和客户端,在本地调试没有问题。把服务器端布署到 11 这台服务器上后,在 164 客户端连接却总是抛错:
java.rmi.ConnectException: Connection refused to host:127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod
(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.call(Unknown Source)
at RMI.Client.callRMI(Client.java:39)
at RMI.Client.main(Client.java:53)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket
(Unknown Source)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket
(Unknown Source)
... 9 more
也就是 IP 被指向 127.0.0.1 了,而客户端发起连接的时候 IP 绝对是写的 IP 192.168.39.11

RMI 问题 3 分析:

这就是典型的服务器有多个 ip 引起的 rmi 连接问题。

RMI 问题 3 解决:

         解决方法有三:

<!---->1.       <!---->服务器端添加代码: System.setProperty("java.rmi.server.hostname""192.168.39.11" );

可写在全局监听器里成为全局变量。

<!---->2.  <!----> RMI 服务器上 root 身份登录,输入 Vi /etc/hosts ,在第一行添加 192.168.39.11     ieie

<!---->3.  <!---->若是用 spring, 则在 RmiServiceExporter 中添加属性 <property name="registryHost"  value="192.168.39.11" />

总结 :RMI固然好用,但得慎用,以上问题困扰甚久,终得解决:)

 

分享到:
评论

相关推荐

    Java RMI 例子 和一些常见问题

    常见问题及解决策略 - **网络问题**:检查网络连接,确保服务器和客户机之间的通信畅通。 - **端口冲突**:RMI默认使用1099端口,可能与其他应用冲突,可更改RMI注册表端口。 - **安全性**:RMI默认使用匿名连接,...

    java Spring+RMI入门程序源代码

    Java Spring 框架与 Remote Method Invocation (RMI) 的结合使用是构建分布式应用程序的一种常见方式。本项目提供了一个入门级的源代码示例,帮助开发者理解如何在 Spring 环境下集成 RMI 技术。以下是关于这两个...

    spring RMI 实用分享

    四、常见问题与解决策略 1. 远程调用超时:检查网络环境,调整Spring的`RmiClientInterceptor`或`RmiServerInterceptor`的超时设置。 2. 类装载问题:确保客户端和服务端有相同的类路径,或者使用`java.rmi.server...

    java RMI 总结

    Java Remote Method Invocation ...理解其核心概念、工作流程以及解决常见问题的策略,是成为一名熟练的Java RMI开发者的关键。在实际项目中,结合其他技术如EJB、JMS或Spring框架,可以构建出更为复杂的分布式系统。

    Spring API

    9.9. 常见问题的解决方法 9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 ...

    SpringRecipes

    ### Spring Recipes:问题与解决方案的方法论 #### 书籍概述 《Spring Recipes》是一本专注于Spring框架的实用指南,由Gary Mak编写,Sam Brannen(SpringSource的技术评审员)和Kris Lander进行了技术审阅。该书...

    Spring中集成Hessian的问题

    **常见问题与解决方案** 在实际应用中,可能会遇到一些问题,如网络连接错误、序列化异常、版本兼容性问题等。解决这些问题通常需要检查服务端和客户端的配置,确保URL正确,服务正常运行,以及Hessian库版本匹配。...

    Pro Spring 3.pdf

    Spring框架是一种用于构建Java应用的强大、轻量级框架,它提供了一种解决企业级应用开发中常见问题的统一方法。Spring的核心功能包括依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented ...

    spring官方文档

    **Spring框架**是一个为企业级应用提供一站式解决方案的轻量级框架。其模块化的设计使得开发者可以根据具体需求选择合适的组件进行集成。Spring框架的核心特性包括但不限于: - **控制反转(IoC)**:一种设计模式...

    Spring开发指南

    它不仅涵盖了Spring的基本概念和设计思想,还包括了具体实现和应用技巧,以及在实际项目中可能遇到的常见问题的解决方案。通过这份指南,开发者可以系统地学习和掌握Spring框架,更高效地进行Java应用的开发和维护。

    spring缓存

    缓存技术被广泛应用于解决这些问题,通过存储常用数据或计算结果,减少数据库访问,提高响应速度。Spring框架提供了一套灵活的缓存抽象,允许开发者选择不同的缓存实现,如EHCache。 1.2 主要特性 Spring的缓存抽象...

    RMI规范说明

    远程方法调用(Remote Method Invocation,RMI)是Java平台上的...尽管现代的Java技术如JMS、Web服务和分布式框架(如Spring Cloud)在某些场景下提供了更强大的解决方案,但RMI依然是理解和掌握Java分布式计算的基础。

    12Spring以及框架相关面试问题汇总1

    Spring框架是Java开发中不可或...总结来说,Spring框架提供了全面的解决方案,涵盖了Web应用的各个方面,包括控制层、数据访问层、事务管理、缓存等。了解并熟练掌握这些知识点对于成为一名专业的Java开发者至关重要。

    spring整合EhCache 的简单例子

    Spring 整合 EhCache 是一个常见的缓存管理方案,它允许我们在Spring应用中高效地缓存数据,提高系统性能。EhCache 是一个开源、基于内存的Java缓存库,适用于快速、轻量级的数据存储。现在我们来详细探讨如何在...

    Pro Spring Integration (Apress)

    Spring Integration的目标是解决企业级应用中的水平集成问题,即如何在不同的应用程序和服务之间高效地传递数据。 #### 二、Spring Integration的特点 - **轻量级**:Spring Integration非常轻量,几乎不需要额外...

    Spring Recipes: A Problem-Solution Approach

    这本书涵盖了Spring框架的核心组件以及企业级应用开发中的常见问题,旨在帮助开发者高效地解决实际工作中遇到的问题。 Spring框架是Java平台上的一个开源框架,它的核心设计目标是简化Java企业级应用的开发。通过...

    Spring中文帮助文档

    9.9. 常见问题的解决方法 9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 ...

Global site tag (gtag.js) - Google Analytics