注:转载于http://www.blogjava.net/hubin/archive/2008/04/14/171116.html

在开始写例子之前还是先,了解一下RMI的相关知识.
什么是RMI
远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制,
使用这种机制,某一台计算机上的对象在调用另外一台计算机上的方法时,使用的程
序语法规则和在本地机上对象间的方法调用的语法规则一样。

优点
这种机制给分布计算的系统设计、编程都带来了极大的方便。
只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。
任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。

1、面向对象:
RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。
也就是说,可以将类似Java哈西表这样的复杂类型作为一个参数进行传递。

2、可移动属性:
RMI可将属性从客户机移动到服务器,或者从服务器移动到客户机。

3、设计方式:
对象传递功能使您可以在分布式计算中充分利用面向对象技术的强大功能,如二层和三层结构系统。
如果用户能够传递属性,那么就可以在自己的解决方案中使用面向对象的设计方式。
所有面向对象的设计方式无不依靠不同的属性来发挥功能,如果不能传递完整的对象——包括实现和类型
——就会失去设计方式上所提供的优点。

4、安全性:
RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。
RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。
5、便于编写和使用
RMI使得Java远程服务程序和访问这些服务程序的Java客户程序的编写工作变得轻松、简单。
远程接口实际上就是Java接口。
为了实现RMI的功能必须创建远程对象任何可以被远程调用的对象必须实现远程接口。但远程
接口本身并不包含任何方法。因而需要创建一个新的接口来扩展远程接口。
新接口将包含所有可以远程调用的方法。远程对象必须实现这个新接口,由于新的接口扩展了
远程接口,实现了新接口,就满足了远程对象对实现远程接口的要求,所实现的每个对象都将
作为远程对象引用。

个人总结:
RMI说白了,就是提供了一种远程的方法调用。 这种调用简单方便,可以传递复杂java对象。现在流行的j2ee中的EJB的底层实现技术就是RMI,EJB的调用就是经过封装的,更高级的RMI调用。

下面我们就来写一个RMI的程序:
前提:

在Eclipse中装入RMI插件(从附件下载)。下载解压后将features和 plugins分别拷到eclipse的对应文件夹中,然后重启Eclipse,最好能在cmd窗口中加上 -clean启动。


一.创建RMI程序的6个步骤:
1.定义一个远程接口
2.实现这个远程接口
3.开发服务器
4.开发客户机
5.生成存根和基干,启动RMI注册表、服务器和客户机 (可在dos中用rmic生成存根和基干)

二. 程序详细说明

先建一个java工项"rmiDemo1"(我的是I:\codeDemo\elispe\rmidemo1\rmiDemo1,在这里要特别注意的存放目录)

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

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface SayHello extends Remote {//需要从Remote继承
public String sayHello(String info)throws RemoteExceptio //需要抛出remote异常n;

}

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

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class SayHelloImpl extends UnicastRemoteObject implements SayHello {

protected SayHelloImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}

public String sayHello(String info) throws RemoteException {
return "hello="+info;
}

}

实现接口的类必须继承UnicastRemoteObject类。
扩展java.rmi.server.UnicastRemoteObject
UnicastRemoteObject顾名思义,是让客户机与服务器对象实例建立一对一的连接。

3.生成程序的根文件
在rmiDemo1上单击右键,选择RMI--Enable Stubs Generation,自动会在bin/文件夹中生成SayHelloImpl_Stub.class。

4.创建服务器类

import java.rmi.*;
import java.net.*;
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2007</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*/
public class SayRmiServer {
public SayRmiServer() {
}

public static void main(String args[]) throws RemoteException, MalformedURLException {
SayHelloImpl add = new SayHelloImpl();
Naming.rebind("addnumbers", add);
}
}

5.创建Client类

import java.rmi.*;
import java.net.*;

/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2007</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*/
public class SayRmiClient {
public SayRmiClient() {
}
public static void main(String args[]) throws RemoteException,
MalformedURLException, NotBoundException {
String url = "rmi://127.0.0.1/addnumbers";
SayHello add = (SayHello) Naming.lookup(url);
String result = add.sayHello("hubin");
System.out.println(result);
}

}
三.运行调试项目


在运行之前需要进行一下设置,否则,会提示错误信息,说找不到stub类。


1、启动RMIRegistry

Eclipse菜单window->show view->others,在弹出菜单中选择RMI Views->RMI Registry Inspector,这是会多出来一个窗口,这里可以显示已经注册的RMI应用。

点击工具条上的RMI Plugin图标,在菜单中选择Start Local Registry。

在 运行-->cmd--->cd 进入你项目生成class文件所在目录,如我的是( cd I:\codeDemo\elispe\rmidemo1\rmiDemo1\bin,在当前目录下,直接运行rmiRegistry命令),如果不在存处注 册,你的服务会总是联结不上的.


注意这个只需要启动一次,除非你把它关掉。
2、配置运行RMI服务

右键点击左边树中的RMI_Server.java文件,菜单Debug As ->RMI Application。在弹出对话框中找到RMI Properties标签页。

这时这里前两项显示红色。

选中java.security.police项的value框,点击选择按钮会出现文件选择对话框,我们这里设置成C:\Java \jre1.5.0_05\lib\security\java.security。就是jre的安全策略配置文件,要选择成泥当前用的jdk的侧略文 件。


选中第二项java.rmi.server.codebase的value项,这里选择编译后类包所在的文件夹。点击选择按钮->add按钮 ->pick from workspace,选择当前工程RMITest的bin文件夹。这里是file:/I:\codeDemo\elispe\rmidemo1 \rmiDemo1\bin。
点击apply按钮。
点击debug按钮。

4.单击RmiServer选择Run as--RMI Application
5.单击RmiClient选择Run as--Java Application