Java中RMI的实现机制

关键字: rmi

我下面贴出代码的例子是网上转来的,我在这里主要要说一下在跑通这个例子可能会遇到的问题和解决办法,希望能为初学的朋友节省时间,以便快速入门 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 !!
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值