RMI從Java1.1開始,RMI使得運行於不同JVM(包括不同主機)上的Java應用程序可以彼此通話。
即:一個JVM中的Java應用程序可以調用另一JVM上的對象(遠程對象)所定義的方法。
Java RMI有著重要的意義。RMI在Java網絡編程和高級編程中都有重要的應用,如EJB, Jini等。
Java2對RMI做了很多增強和改進,如安全性,動態代碼下載等。
本文給出了一個最簡單的例子,以說明其中的一些基本原理。本文的特點是注重了實際開發和真正的運行
環境相結合,模擬了RMI真正的開發和運行過程。
1. 實現遠程接口,生成遠程對象,存根(Stub)和框架(Skeleton)
實現遠程接口,遠程接口告訴JVM:實現了該接口的對象可以遠程調用及有哪些方法可以調用。
本例子中定義了sayHello()。由於遠程調用會涉及到網絡通訊,因此這些方法都要拋出RemoteException.
遠程接口和遠程對象可以由A開發,並把遠程接口(Hello)d打包分給Client端開發者B。
建立f:server目錄,把Hello.java和HelloImpl.java拷貝到該目錄中。
// Hello.java
package jdeveloper.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
生成遠程對象.
// HelloImpl.java
package jdeveloper.rmi;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject
implements Hello {
public HelloImpl() throws RemoteException {
super();
}
public String sayHello() {
return "Hello World!";
}
public static void main(String args[]) {
// Create and install a security manager
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
Hello obj = new HelloImpl();
// Bind this object instance to the name "HelloServer"
Naming.rebind("HelloServer", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
存根(Stub)和框架(Skeleton)
f:
cd server
javac -d . Hello.java
javac -d . HelloImpl.java
rmic -d . jdeveloper.rmi.HelloImpl
jar cvf hello.jar jdeveloper
miHello.class 把hello.jar分發給Client端的開發者B。
存根(Stub)的存放!
存根(Stub)是動態下載的。Client通過存根(Stub)和遠程對象的框架(Skeleton)通訊,對Client來
講就象操作本地對象一樣。在大多數情況下,可下載的代碼放到http服務器的某個目錄中。本例子放到http://hjc/rmi下。
hjc:機器名,rmi:http的一個目錄。假如只是單機測試則可以放到某個目錄下 如f:serverclasses.
本文將對以上兩種方法都給出運行的步驟(policy文件和bat文件)。
2. 實現Client端程序
// HelloClient.java