RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据。RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对 象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模 式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这 是一次远程通讯的革命,为远程通信开辟新的里程碑。
开发步骤:
1、 编写并且编译接口的Java代码
2、 编写并且编译接口实现的Java代码
3、 从接口实现类中生成桩(Stub)和框架(Skeleton)类文件
4、 编写远程服务的主运行程序
5、 编写RMI的客户端程序
6、 安装并且运行RMI系统
1、 接口 第一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能,下面是源程序:
public interface Calculator extends
public long add(long a, long b) throws
public long sub(long a, long b)throws
public long mul(long a, long b)throws
public long div(long a, long b)throws
}
注意,这个接口继承自Remote,每一个定义的方法都必须抛出一个RemoteException异常对象。建立这个文件,把它存放在刚才的rmi目录下,并且编译。
2、 接口的具体实现
下一步,我们就要写远程服务的具体实现,这是一个CalculatorImpl类文件:
public class CalculatorImpl extends UnicastRemoteObject implements
protected CalculatorImpl() throws
super();
}
public long add(long a, long b) throws
return
}
public long div(long a, long b) throws
return
}
public long mul(long a, long b) throws
return
}
public long sub(long a, long b) throws
return
}
}
这个实现类使用了UnicastRemoteObject去联接RMI系统。在我们的例子中,我们是直接的从UnicastRemoteObject这个类上继承的,事实上并不一定要这样做,如果一个类不是从UnicastRmeoteObject上继承,那必须使用它的exportObject()方法去联接到RMI。
如果一个类继承自UnicastRemoteObject,那么它必须提供一个构造函数并且声明抛出一个RemoteException对象。当这个构造函数调用了super(),它久激活UnicastRemoteObject中的代码完成RMI的连接和远程对象的初始化。
3、 桩(Stubs)和框架(Skeletons)
下一步就是要使用RMI编译器rmic来生成桩和框架文件,这个编译运行在远程服务实现类文件上。
>rmic CalculatorImpl
在你的目录下运行上面的命令,成功执行完上面的命令你可以发现一个Calculator_stub.class文件,如果你是使用的Java2SDK,那么你还可以发现Calculator_Skel.class文件。
4、 主机服务器
远程RMI服务必须是在一个服务器中运行的。CalculatorServer类是一个非常简单的服务器。
public class
public
try
Calculator c = new
Naming.rebind("rmi://localhost:1099/CalculatorService", c);
} catch
System.out.println("Trouble: "
}
}
/**
* @param args
*/
public static void
new
}
}
建立这个服务器程序,然后保存到你的目录下,并且编译它。
5、 客户端
客户端源代码如下:
public class
public static void
try
Calculator c = (Calculator) Naming
.lookup("rmi://localhost/CalculatorService");
System.out.println(c.sub(4, 3));
System.out.println(c.add(4, 5));
System.out.println(c.mul(3, 6));
System.out.println(c.div(9, 3));
} catch
System.out.println();
System.out.println("MalformedURLException");
System.out.println(murle);
} catch
System.out.println();
System.out.println("RemoteException");
System.out.println(re);
} catch
System.out.println();
System.out.println("NotBoundException");
System.out.println(nbe);
} catch
System.out.println();
System.out.println("java.lang.ArithmeticException");
System.out.println(ae);
}
}
}
6、 运行RMI系统
现在我们建立了所有运行这个简单RMI系统所需的文件,现在我们终于可以运行这个RMI系统啦!来享受吧。
我们是在命令控制台下运行这个系统的,你必须开启三个控制台窗口,一个运行服务器,一个运行客户端,还有一个运行RMIRegistry。
首先运行注册程序RMIRegistry,你必须在包含你刚写的类的那么目录下运行这个注册程序。
>rmiregistry(linux) start rmiregistry(windows)
RMI的安全策略策略文件在 JDK 目录下的jre/lib/security/java.policy 的最后面加上下面这句话
grant{
permission java.security.AllPermission "","";
};
这条命令表示允许任何人作任何事情,
修改完后运行命令 rmiregistry ,然后就不用管他了
运行CalculatorServer和CalculatorClient
输出结果
注意:请设置好classpath和文字编码问题
-classpath XXX
-encoding UTF-8