开发 RMI时遇到的问题

ggyy1031 2011-02-28 07:48:18
需要用RMI实现远程调用

因为是web应用,是用tomcat来发布,有几个问题,希望做过的大虾能为我解惑。

1 服务端必须在tomcat启动完成之前开启,其实也只是执行服务端类的一个方法就行。而服务端的绑定对象是通过spring 来注入的。所以第一个问题就是:什么时候来执行这个方法,在哪里执行。

2 我尝试写了一个servlet来启动这个方法,在setter方法中看到注入的对象为
...service = org.springframework.aop.framework.JdkDynamicAopProxy
然后在servlet的init方法中进入创建服务器端的方法,该对象变为null。第二个问题就是,为什么会出现这种情况。

3 我在远程对象的一个方法中返回了另一个对象
class UserService{

voidgetUserDao(UserDao userDao){
this.userDao = userDao;

}

}




然后在客户端想通过这个方法来获得userDao的引用时出错。
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: com.dao.UserDaoImpl (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.getUserDao(Unknown Source)
at com.test.RmiClient.main(RmiClient.java:24)
Caused by: java.lang.ClassNotFoundException: com.dao.UserDaoImpl (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
... 4 more


希望有知道的大虾能解答下。如果哪位大哥有这方面的例子共享下,小弟将不胜感激。
...全文
403 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ggyy1031 2011-03-01
  • 打赏
  • 举报
回复
谢谢humanity。
但是因为我的应用是用tomcat来起的,所有main class我也不知道在哪。。
humanity 2011-03-01
  • 打赏
  • 举报
回复
不一定,只要接口的远程方法中不使用这些数据库相关的参数,就不需要通过网络传递数据库的对象,只要把数据库访问隔离在服务端就可以了。不然的话,EJB 访问数据库岂不成了天文夜谭。

[Quote=引用 7 楼 nanman 的回复:]

客户端没有UserDaoImpl这个类 ,报错了
UserDaoImpl这种对象不能远程传递,链接数据库的,传递了连不上数据库
传递的对象服务器/客户端两边版本要保持一致
[/Quote]
humanity 2011-03-01
  • 打赏
  • 举报
回复
客户端的代码中的 main class 的开始就要 System.setSecurityManager(new RMISecurityManager()); 以启用 RMI Class Loader; (no security manager: RMI class loader disabled)。

客户端运行时的命令行加个 -Djava.security.policy=$JavaPolicy文件路径。一般这里面给 AllPermission 来测试的。

客户端运行时的命令行加个 -Djava.rmi.server.codebase=file://C:/xxx/classes/ 或 =http://remoteserver/classes/,注意后面的 / 是必须的,因为真实地加载类 com.training.A 时会用 http://remoteserver/classes/com/training/A.class 来取得资源。

不知道 RMI Class Loader 什么原理工作,不过我们可以大胆猜测一下它是类似下面这种行为,Thread.currentThread().setContextClassLoader(new URLClassLoader[]{$我们的 codebase URL}, Thread.currentThread().getContextClassLoader());


ggyy1031 2011-03-01
  • 打赏
  • 举报
回复
有人知道前面两个问题的答案吗?
谁有这方面的案例能给个例子吗?谢谢
ggyy1031 2011-02-28
  • 打赏
  • 举报
回复
我现在就是要读写远程机器上的数据库啊。不能连接数据库那不悲剧了。
  • 打赏
  • 举报
回复
客户端没有UserDaoImpl这个类 ,报错了
UserDaoImpl这种对象不能远程传递,链接数据库的,传递了连不上数据库
传递的对象服务器/客户端两边版本要保持一致
ggyy1031 2011-02-28
  • 打赏
  • 举报
回复
都有序列化。
  • 打赏
  • 举报
回复
远程传递对象需要 实现序列化 implements Serializable
ggyy1031 2011-02-28
  • 打赏
  • 举报
回复
新手初级,看了几个例子就开始整的。。知道就说下呗
龙四 2011-02-28
  • 打赏
  • 举报
回复
都是用了rmi了,这么低级的错误都找不到原因?
ggyy1031 2011-02-28
  • 打赏
  • 举报
回复
这个没找到类,原因应该是路径没找到,目前还没有解决办法
yuppy 2011-02-28
  • 打赏
  • 举报
回复
java.lang.ClassNotFoundException 异常不是写了找不到类么...

找找你的jar包对不对

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧