用户操作
[即时聊天] [发私信] [加为好友]
张洪伟ID:Jackiezhw
12614次访问,排名9547,好友0人,关注者0人。
Jackiezhw的文章
原创 28 篇
翻译 0 篇
转载 8 篇
评论 0 篇
最近评论
文章分类
收藏
    相册
    Java Techonology
    BlogJava上圆月弯刀的Blog
    Java 调试平台
    自我成长
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 java.rmi.server.codebase Property介绍收藏

    新一篇: RMI服务提供者注册服务的2种方式 | 旧一篇: RMI中使用工厂模式

    在使用RMI编程的时候,有时会出现如下的错误:

     java.rmi.ServerException: RemoteException occurred in server thread; nested excption is:
            java.rmi.UnmarshalException: error unmarshalling arguments; nested excetion is:
            java.lang.ClassNotFoundException: cn.ac.ict.hla.rmi.HelloImpl_Stub
            at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:39)
            at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
            at sun.rmi.transport.Transport$1.run(Transport.java:159)
            at java.security.AccessController.doPrivileged(Native Method)

    开始的时候以为在运行RMI Server部分的lauch Code时找不到类,即使指定了classpath还是不行。

    其实不是lauch code找不到类定义,而是rmiregistry找不到类定义,这时有两种解决办法

    1.  在类所在目录运行rmiregistry;

    2. 在运行lauch code的时候使用java.rmi.server.codebase指定类路径;

    第1种方案是有局限的,因为不可能所有的类都在一个目录下,所以比较好的方式还是使用第2种方法。不过在使用第2种方法的使用要注意格式问题,例如:

    -Djava.rmi.server.codebase=http://YourServerName/YourPackagePathName/

    -Djava.rmi.server.codebase=http://webline/public/mystuff.jar


     -Djava.rmi.server.codebase=file:/d:\SomeSource\Testproject\java\rmi\Hello2\ 

    使用本地文件目录时必须使用绝对路径,而且所有的codebase后面都需要有个 \  或 /   来表示这是一个目录,也可以是一个jar文件。如果去掉它们就会报错。

    A codebase can be defined as a source, or a place, from which to load classes into a virtual machine.

    我们可以把CLASSPATH看作是local codebase,而RMI和applet中使用的是remote codebase。

    Applet中codebase的使用方式:

    1. 客户浏览器请求一个不做客户CLASSPATH中的类

    2. applet的类定义被客户从服务器上使用HTTP下载下来

    3. applet在客户机上执行

    RMI中codebase的使用方式:

    1.  远程对象服务器通过设定java.rmi.server.codebase 属性指定远程对象的codebase。RMI server向RMI registry注册了一个远程对象,绑定到一个name上,在server VM上设置的codebase被通知给了RMI registry;
    2.  RMI client请求一个特定名字的远程对象的引用,用来调用远程方法;
    3.  RMI registry返回一个到被请求类的引用。如果这个stub实例的类定义可以在client的CLASSPATH中找到,Client会本地加载这个类;如果client的CLASSPATH中没有类定义,client会尽量从远程对象的codebase中获取类定义;
    4.  client从codebase中请求类定义。
    5.  对请求的stub的类定义被下载到client;
    6.  这时,client就有了调用远程方法的所有信息。这个stub成为一个对Server上remote对象的代理,与Applet不同的是,Applet在本地执行,而RMI在remote VM中执行;

    注意:在server向rmiregistry注册的时候,也会产生第4步和第5步,不过请求的角色不是client,而是rmiregistry

    codebase不但可以用于加载stub的类定义,也可以用来加载任何其他的类定义,当远程方法的一个参数或者返回值对象的类定义在本地 CLASSPATH中找不到时,也可以使用codebase来加载,如图示:

     客户发起一个包含Remote Server不知道的类的实例的远程调用,Remote从codebase中下载该类的定义。

    注:一个典型的情况是一个方法的参数是个Interface,但实际传人的参数是某个实现了这个接口的类,这时即使Remote没有这个类定义,编译也可以通过,但是具体调用时会找不到类定义。

    注:这种情况下的codebase要在client端指定,如果不指定,Server就会错用自己的codebase。

     

     

    发表于 @ 2007年05月30日 18:55:00|评论(loading...)|编辑

    新一篇: RMI服务提供者注册服务的2种方式 | 旧一篇: RMI中使用工厂模式

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © Jackiezhw