JAVA RMI实例

创建RMI程序的6个步骤:
1、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
2、定义一个实现该接口的类。
3、使用RMIC程序生成远程实现所需的残根和框架。
4、创建一个服务器,用于发布2中写好的类。
5. 创建一个客户程序进行RMI调用。
6、启动rmiRegistry并运行自己的远程服务器和客户程序

1步
定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常

Java代码  
1.package rmi;   
2.  
3.import java.rmi.RemoteException;   
4.  
5./**  
6. * 第一步,定义一个远程接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常  
7. */  
8.  
9.//接口里定义一个返回字符串的远程方法 SayHello(),这个远程接口 I_Hello必须是public的   
10.//它必须从java.rmi.Remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.RemoteException。   
11.//   
12.//抛出这个异常的原因:由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生   
13.//因此,所有的RMI操作都应放到try-catch块中   
14.  
15.  
16.//需要从Remote继承   
17.public interface I_Hello extends java.rmi.Remote{   
18.  
19.    //需要抛出remote异常   
20.    public String SayHello() throws RemoteException;   
21.}  
package rmi;

import java.rmi.RemoteException;

/**
* 第一步,定义一个远程接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常
*/

//接口里定义一个返回字符串的远程方法 SayHello(),这个远程接口 I_Hello必须是public的
//它必须从java.rmi.Remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.RemoteException。
//
//抛出这个异常的原因:由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生
//因此,所有的RMI操作都应放到try-catch块中


//需要从Remote继承
public interface I_Hello extends java.rmi.Remote{

    //需要抛出remote异常
    public String SayHello() throws RemoteException;
}

2步
定义一个实现该接口的类

Java代码  
1.package rmi;   
2.  
3.import java.rmi.*;   
4.import java.rmi.server.UnicastRemoteObject;   
5.  
6./**  
7. * 第二步,定义一个实现远程接口的类  
8. */  
9.  
10.//实现接口的类必须继承UnicastRemoteObject类,扩展java.rmi.server.UnicastRemoteObject   
11.  
12.public class Hello extends UnicastRemoteObject //必须从UnicastRemoteObject 继承   
13.        implements I_Hello {   
14.    public Hello() throws RemoteException{ //需要一个抛出Remote异常的默认初始化方法   
15.    }   
16.  
17.    public String SayHello(){ //这个是实现I_Hello接口的方法   
18.        return "Hello world !!";   
19.    }   
20.}  
package rmi;

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

/**
* 第二步,定义一个实现远程接口的类
*/

//实现接口的类必须继承UnicastRemoteObject类,扩展java.rmi.server.UnicastRemoteObject

public class Hello extends UnicastRemoteObject //必须从UnicastRemoteObject 继承
        implements I_Hello {
    public Hello() throws RemoteException{ //需要一个抛出Remote异常的默认初始化方法
    }

    public String SayHello(){ //这个是实现I_Hello接口的方法
        return "Hello world !!";
    }
}

3步
使用RMIC程序生成远程实现所需的残根Stub 和 框架
这一步是关键,也是最容易出问题的地方,需要多说几句:
在RMI中,客户机上生成的调动调用参数和反调动返回值的代码称为残根。有的书上称这部分代码为“主干”。
服务器上生成的反调动调用参数和进行实际方法调用调动返回值的代码称为框架

2中的Hello编译好以后,我们就可以用RMIC命令来生成残根Stub
操作是:在cmd下到Hello.class 所在目录,运行以下命令:rmic Hello
命令执行完以后,将会在当前目录生成一个 Hello_Stub.class 这个就是我们远程调用时需要的类
如果您是照着上面的方法做的,现在应该会遇到报的第一个错:Class xxx not found
解决方法分两步
首先,打开环境变量,将项目路径D:\workspace_bohai_FXM\ztest(项目名)\rmi(包名)添加到classpath中,在cmd下set一下,看看是否设置好了
然后,cmd下输入要注意,如果你要rmic的.class文件在包下,就必须cd到目标.class文件所在包的目录下,此例 是:D:\workspace_bohai_FXM\ztest>rmic rmi.Hello,在你的rmi目录下会生成两个文件Hello_Stub.class和Hello_Skel.class。 Hello_Stub.class 这个就是我们远程调用时需要的类


4步
创建一个服务器,用于发布2中写好的类

Java代码  
1.package rmi;   
2.  
3.import java.rmi.*;   
4.  
5./**  
6. * 4步,创建一个服务器,用于发布类Hello  
7. */  
8.  
9.public class RMI_Server {   
10.    public static void main(String[] args) {   
11.        try {   
12.            //实例化要发布的类   
13.            Hello hello = new Hello();   
14.            //绑定RMI名称 进行发布,即客户端通过这个名字查找的对象就是hello这个实例   
15.            Naming.rebind("RMI_Hello", hello);   
16.            System.out.println("=== Hello server Ready === ");   
17.        } catch (Exception exception) {   
18.            exception.printStackTrace();   
19.        }   
20.    }   
21.}  
package rmi;

import java.rmi.*;

/**
* 4步,创建一个服务器,用于发布类Hello
*/

public class RMI_Server {
    public static void main(String[] args) {
        try {
            //实例化要发布的类
            Hello hello = new Hello();
            //绑定RMI名称 进行发布,即客户端通过这个名字查找的对象就是hello这个实例
            Naming.rebind("RMI_Hello", hello);
            System.out.println("=== Hello server Ready === ");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

5步
创建一个客户程序进行RMI调用

Java代码  
1.package rmi;   
2.  
3./**  
4. * 5步,创建一个客户程序进行RMI调用  
5. */  
6.  
7.import java.rmi.*;   
8.  
9.public class RMI_Client {   
10.    public static void main(String[] args) {   
11.        try {   
12.            I_Hello hello = (I_Hello) Naming.lookup("RMI_Hello"); //通过RMI名称查找远程对象   
13.            //如果是异地的RMI调用请参照    rmi://127.0.0.1:1099/RMI_Hello            
14.            //端口1099是默认的RMI端口,如果你启动 rmiregistry 的时候,没有指定特殊的端口号,默认就是1099   
15.  
16.            System.out.println(hello.SayHello()); //核心句:调用远程对象的方法   
17.        } catch (Exception e) {   
18.            e.printStackTrace();   
19.        }   
20.    }   
21.  
22.}  
package rmi;

/**
* 5步,创建一个客户程序进行RMI调用
*/
import java.rmi.*;

public class RMI_Client {
    public static void main(String[] args) {
        try {
            I_Hello hello = (I_Hello) Naming.lookup("RMI_Hello"); //通过RMI名称查找远程对象
            //如果是异地的RMI调用请参照    rmi://127.0.0.1:1099/RMI_Hello         
            //端口1099是默认的RMI端口,如果你启动 rmiregistry 的时候,没有指定特殊的端口号,默认就是1099

            System.out.println(hello.SayHello()); //核心句:调用远程对象的方法
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

6步
启动rmiRegistry并运行自己的远程服务器和客户程序
cmd下运行命令rmiregistry,然后放在一边不用管他(第一个cmd窗口)
然后通过cmd运行Server,直接在IDE里运行一般会报错:找不到Stub类,需要用下面的命令来运行,命令里指定了stub类的路径
cmd到D:\workspace_bohai_FXM\ztest>目录下运行java.exe -Djava.rmi.server.codebase=file:/D:\workspace_bohai_FXM\ztest/ rmi.RMI_Server
(注意:ztext是项目名,rmi是包,最后的那个ztest/后有一个空格)
回车后cmd会显示:=== Hello server Ready ===
(代表Server成功启动,第二个cmd窗口)
然后在运行Client就会看到你千辛万苦远程方法调用的结果:Hello world !!

上文转自:http://damiao-cn.iteye.com/blog/228948    原创不知是谁

弄了好几个小时,最后还是跑起来了。
报Hello_Stub.class这个找不到,网上查了哈,说要把Hello_Stub.class所在目录加到CLASSPATH里面,果然问题解决,再重新注册成功。

JAVA的RMI和.NET的remoting大同小异,原理基本一样,都用于跨域访问对象。

posted @ 2012-05-10 21:35  宁静.致远  阅读(488)  评论(0编辑  收藏  举报