2008-11-15
rmi 找不到stub问题
转自http://sun-cat.iteye.com/blog/80278
转自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**:...
以下是对Java RMI的详细解释以及一些常见问题的解答。 ### 1. RMI基本概念 RMI的核心是远程接口(Remote Interface),它定义了可以在远程对象上调用的方法。这些方法的实现位于远程服务器上,客户端通过调用这些...
此外,RMI还涉及到安全性问题,因为远程对象可能会执行敏感操作。Java RMI支持通过JVM的安全管理器设置权限,以限制远程对象的访问和行为。 总之,Java RMI是构建分布式Java应用的重要工具,它简化了网络通信的复杂...
- `RMIServer`可能包含了服务器端的主程序,它注册远程对象到RMI注册表,使得客户端可以通过名字查找并调用。 - 项目可能包含一个或多个远程接口类,定义了可供客户端调用的服务方法。 - 服务器端会有一个或多个...
1. **导出远程对象**: 开发者创建实现远程接口的类,并实例化一个远程对象,然后使用`java.rmi.Naming.rebind()`或`UnicastRemoteObject.exportObject()`将其导出到网络上。 2. **注册远程对象**: 将导出的对象注册...
如果出现异常,如网络问题或找不到远程对象,客户端代码需要捕获并处理这些异常。 总结来说,RMI提供了一种透明的方式来调用远程对象的方法,使得开发者可以创建分布式的Java应用程序而无需深入理解网络编程的复杂...
- **JNDI和Stub/Skeleton**:早期的RMI需要Stub和Skeleton,但现在JDK已经自动处理了这些细节,开发者无需手动创建。 4. **安全性**: - RMI支持SSL加密通信,可以通过配置`java.security.policy`文件来设定权限...
- 接口的具体实现类需要继承`java.rmi.server.UnicastRemoteObject`,这样可以获取到RMI所需的基础设施。实现类需要抛出`RemoteException`,并实现接口中定义的所有方法。例如,`LoadFileService`类。 ```java ...
- **异常处理**:RMI中的异常通常包括网络连接问题、对象不存在、版本不匹配等,需要适当地捕获和处理。 - **RMI与EJB的结合**:EJB(Enterprise JavaBeans)是Java EE的一部分,RMI常用于EJB组件之间的通信,尤其...
使用RMI进行分布式编程时,需要注意网络延迟、异常处理、安全性等问题。例如,网络故障可能导致调用失败,此时需要设计合适的重试策略;RMI的调用可能会抛出`java.rmi.RemoteException`,必须捕获并处理;此外,由于...
3. 当客户端调用远程对象的方法时,RMI会自动序列化参数,通过网络发送到服务器端。 4. 服务器端接收到请求后,反序列化参数,执行相应的远程方法,然后将结果序列化回传给客户端。 5. 客户端接收到结果,反序列化...
7. **异常处理**:由于网络通信的不可靠性,RMI调用可能会抛出各种异常,如ConnectException(连接问题)、NoSuchObjectException(找不到对象)等。因此,编写RMI程序时需要妥善处理这些异常。 在实际应用中,使用...
- RMI不直接支持HTTP或HTTPS协议,可能需要额外的适配层。 - 对于大型分布式系统,RMI的管理复杂度会增加,可能需要更高级的框架如JMS或EJB。 7. **其他相关技术** - Java的CORBA支持提供更通用的分布式对象模型...
在这个场景中,我们讨论的是如何利用RMI来实现文件或图片的上传功能,从客户端到远程服务器。 首先,我们需要理解RMI的基本原理。RMI包括三个主要组件:远程接口、远程实现和RMIServer。远程接口定义了可以在远程...
根据提供的文件信息,我们可以深入探讨Java RMI(Java Remote Method Invocation)的相关知识点,包括其概念、原理、体系结构以及一个具体的示例。 ### RMI的概念 RMI是一种Java技术,它允许开发者创建分布式应用...
- RMI 默认不允许从远程客户端加载类。 - 使用 RMI 的安全性策略文件配置安全设置。 3. **性能优化:** - 考虑使用缓存减少远程调用次数。 - 对于大量数据传输,考虑使用更高效的数据格式(如二进制)。 #### ...
例如,`rmic`用于生成远程对象的stub和skeleton,`rmiregistry`用于启动RMI注册表,`rmid`管理服务器端的Java虚拟机。 **安全性与性能优化** 尽管RMI简化了分布式计算,但也需要注意安全性和性能优化: - 安全性:...
- ** stub 和 skeleton**:RMI系统使用代理(stub)对象作为远程对象的本地代表,而skeleton对象则在远程服务器上接收和分发调用。在现代Java版本中,这些组件由JDK自动处理。 2. **RMI步骤**: - **注册远程对象...
6. **异常处理**:由于网络通信的不稳定性,RMI调用可能会出现各种异常,如ConnectException(连接失败)、NoSuchObjectException(找不到对象)或RemoteException(远程调用过程中的任何异常)。良好的异常处理策略...