转自http://bbs.cjsdn.net/post/view?bid=2&id=35316&sty=3
今天,又看了一回JBUILDER关于RMI的帮助,终于解决了些重要的疑问。看过这阵子贴子的人应该都知道这段时间关于RMI有很多问题出现,我也看了那些贴子,有的问题没有解决,有的“解决”了,但根本就没有用正确的方法。以下是我的经验(但是这不是RMI入门教程,没有基础的请暂时收藏,以后学RMI时相信可以给你些帮助)。这些东西过来人肯定知道,但是为什么他们从来都不告诉我们呢?是不愿,还是不屑呢?
首先要说的是最常见的一个问题,客户端找不到XXX_stub.class文件。这个问题问的人最多(包括我自己以前也来问过)。在CSDN上,甚至于我看到的两本(我就看过两本)译过来的中文书上提出的解决办法,或潜在的解决方法就是在java的参数-classpath中加入XXX_stub.class文件相应路径。确实,问题一下子解决了,但是我心里感觉十分不妥!有没有人想过,对于一个客户端,难道每个客户端都要在本地有一个XXX_stub.class文件吗?那么试想一个Applet,自己就是临时从server上下载来的,难道它有那个可能在用户本地机上“刚好”找到它要调用的RMI Server 的XXX_stub.class文件吗?所以,XXX_stub.class文件的获得也应该是动态的下载!应该用codebase参数,但是我用codebase参数还是不行(找不到XXX_stub.class文件),试了一个星期都没有解决。(最后再说这个问题的解决)
第二是RMI Server运行时找不到XXX_stub.class文件。有些同志可能是一时大意没有用rmic来编译。但是很多人已经用rmic编译生成了XXX_stub.class文件与骨架文件。但是运行RMI Server时还是找不到XXX_stub.class文件,为什么?其实这个时候,找不到XXX_stub.class文件的不是你的Server,而是rmiregistry程序。你的classpath里当然是有相应录的,但是rmiregistry起动时的路径里可没有。但是,你先别着急把rmiregistry的参数里加上相应路径,因为JBuilder里说千万让rmiregistry知道你的stub文件的路径,因为这样客户端动态下载stub时会出问题(我还没有证实过这一点的正确性)。解决办法是在你起动RMI server时加codebase参数,如下:
java -Djava.rmi.server.codebase=http://YourServerName/YourPackagePathName/ packageName.serverClassName
而你的Web Server的YourServerName/YourPackagePathName/目录下应该有一个与你的包同名的目录,那个目录下有相应stub文件。这个问题就圆满解决了。
第三,不起作用的客户端java.rmi.server.codebase。接着一个问题说,我去掉了客户端classpath目录里的含有stub文件的那一个目录。加上了如下参数:
-Djava.rmi.server.codebase=http://YourServerName/YourPackagePathName/
但是出现错误:
java.lang.ClassNotFoundException: hellormi.GetMessageImpl_Stub (no security manager: RMI class loader disabled)
classNotFoundException的意思是找不到相应类,但是我确认了自已的参数没有错,而且Web Server也没有任何问题。今天在看JBuilder自带帮助时,忽然发现在客户端例子里它竟然也写了:System.setSecurityManager(new RMISecurityManager())。这在我的两本书里都没有看到,而且其中一本书上还明确地说,客户端里不需要任何安全设置。我想了想才大梦初醒:你lookup的时候他当然不用生成安全管理器,但是当你要从server动态下载类的时候它就要用了!加上这一句之后还没有完全OK。要象Server起动时那样给一个java.security.policy属性允许它做相应socket工作(否则会出安全性异常),之后客户端就能自动从主机下载了stub文件了。
最后补充一点,可以通过编码System.setProperty("java.rmi.server.codebase","http://YourServerName/YourPackagePathName/")来代替手工输入属性,但是一定要注意把它放在System.setSecurityManager(new RMISecurityManager())之前。
分享到:
相关推荐
在实验中,我们遇到了两个问题:一是 rmic 命令报错,找不到类 HelloTaskImpl;二是注册中心时遇到的问题。解决方法是修改 java 路径和使用 start rmiregistry 命令。 六、思考题 1. 如何使用 RMI 传递参数? 答...
- **异常处理**:RMI调用可能遇到网络中断、远程对象不存在等问题,因此客户端需要适当地捕获和处理`java.rmi`包下的异常,如`RemoteException`。 3. **RMI通信机制**: - **marshalling**与**unmarshalling**:...
此外,RMI还涉及到安全性问题,因为远程对象可能会执行敏感操作。Java RMI支持通过JVM的安全管理器设置权限,以限制远程对象的访问和行为。 总之,Java RMI是构建分布式Java应用的重要工具,它简化了网络通信的复杂...
如果出现异常,如网络问题或找不到远程对象,客户端代码需要捕获并处理这些异常。 总结来说,RMI提供了一种透明的方式来调用远程对象的方法,使得开发者可以创建分布式的Java应用程序而无需深入理解网络编程的复杂...
- **异常处理**:RMI中的异常通常包括网络连接问题、对象不存在、版本不匹配等,需要适当地捕获和处理。 - **RMI与EJB的结合**:EJB(Enterprise JavaBeans)是Java EE的一部分,RMI常用于EJB组件之间的通信,尤其...
7. **异常处理**:由于网络通信的不可靠性,RMI调用可能会抛出各种异常,如ConnectException(连接问题)、NoSuchObjectException(找不到对象)等。因此,编写RMI程序时需要妥善处理这些异常。 在实际应用中,使用...
- RMI不直接支持HTTP或HTTPS协议,可能需要额外的适配层。 - 对于大型分布式系统,RMI的管理复杂度会增加,可能需要更高级的框架如JMS或EJB。 7. **其他相关技术** - Java的CORBA支持提供更通用的分布式对象模型...
- RMI 默认不允许从远程客户端加载类。 - 使用 RMI 的安全性策略文件配置安全设置。 3. **性能优化:** - 考虑使用缓存减少远程调用次数。 - 对于大量数据传输,考虑使用更高效的数据格式(如二进制)。 #### ...
6. **异常处理**:由于网络通信的不稳定性,RMI调用可能会出现各种异常,如ConnectException(连接失败)、NoSuchObjectException(找不到对象)或RemoteException(远程调用过程中的任何异常)。良好的异常处理策略...
总结来说,"RMI不依赖其他http服务实现代码动态下载"是一个重要的优化,它让Java RMI更加自给自足,提升了整体性能和易用性。通过理解并运用这个特性,开发者可以更有效地构建和维护分布式的Java应用。
RMI的核心机制是通过存根(Stub)和骨架(Skeleton)实现的。存根在客户端扮演服务器端对象的代理角色,它提供了与服务器端相同方法签名的接口,使得客户端能够像调用本地方法一样调用远程方法。当客户端调用存根上...
Remote Method Invocation (RMI) 是Java平台中的一种技术,它允许在不同的计算机之间进行对象间的交互,仿佛...然而,尽管RMI简化了许多工作,但在实际应用中,仍需注意网络延迟、并发控制、容错机制和安全性等问题。
8. **异常处理**:由于网络通信的不确定性,RMI调用可能会抛出各种异常,如java.rmi.ConnectException、java.rmi.UnmarshalException等,需要在客户端妥善处理。 在"rmi_helloworld"这个小程序中,可能包含了以下...
通过RMI,可以轻松实现教学数据的实时处理与广播式传送,解决了大规模网络教学中的瓶颈问题。此外,RMI的可移植性和可重用性使得教育资源的共享更加便捷,促进了在线教育的普及和发展。 五、总结 RMI作为一种强大...
- **集成到J2EE框架中**:RMI常常被封装在各种J2EE项目框架中,例如Spring和EJB等,以提高系统间的服务调用效率。 - **Spring中的实现**:在Spring框架中,实现RMI的过程通常包括以下步骤: - 在服务器端定义服务...
Stub看起来就像是远程对象的一个副本,提供了相同的方法签名,但它并不执行实际的操作,而是负责将调用转换为网络消息,发送到远程服务器。Stub是自动生成的,通过Java的rmic编译器,它将远程接口和其实现转换为Stub...
Java RMI的使用有助于构建可扩展、模块化的分布式系统,但需要注意的是,它并不适合所有场景,特别是在高并发和大流量的情况下,可能需要考虑其他更高效的通信机制,如RMI的替代品如Java的JMS(Java Message Service...
然而,RMI也有其局限性,如不支持异步调用,性能可能受网络延迟影响等。在实际应用中,根据项目需求和场景选择合适的分布式通信技术是非常重要的。 总之,RMI示例展示了如何在Java中创建、部署和调用远程服务。通过...
在Java RMI的新版本中,stub和skeleton的生成和管理已经自动化,开发者通常不需要直接处理。 5. **激活与反激活**:RMI支持对象的激活和反激活,即在需要时创建或销毁远程对象实例,以节省系统资源。 6. **安全性*...
8. **异常处理**:由于网络通信的不确定性,所有RMI调用都应该包含对`RemoteException`的捕获。 详细的学习过程可以参考提供的博客链接,其中应该包含了如何编译、运行和测试这个HelloWorld示例的步骤,以及更深入...