RMI-IIOP出現以前,只有RMI和CORBA兩種選擇來進行分布式程序設計。RMI-IIOP綜合了RMI和CORBA的優點,克服了他們的缺點,使得程序員能更方便的編寫分布式程序設計,實現分布式計算。
首先,RMI-IIOP綜合了RMI的簡單性和CORBA的多語言性(兼容性),其次RMI-IIOP克服了RMI只能用於Java的缺點和CORBA的復雜性(可以不用把握IDL).
下面給出了一個非常的簡單的RMI-IIOP程序,該程序是在上一個例子(Java2 RMI入門的基礎)上修改完成的,可以對比兩個程序的區別。
1. 實現遠程接口,生成遠程對象,存根(Stub)和框架(Skeleton)
實現遠程接口,遠程接口告訴JVM:實現了該接口的對象可以遠程調用及有哪些方法可以調用。
本例子中定義了sayHello()。由於遠程調用會涉及到網絡通訊,因此這些方法都要拋出RemoteException.
遠程接口和遠程對象可以由A開發,並把遠程接口(Hello)d打包分給Client端開發者B。
建立f:
mi_iiop目錄,把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_iiop;
import javax.naming.*;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
//import java.rmi.server.UnicastRemoteObject;
import javax.rmi.PortableRemoteObject;
public class HelloImpl extends PortableRemoteObject
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"
//***** old code for rmi
// Naming.rebind("HelloServer", obj);
//***** new code for rmi-iiop
Context initialNamingContext = new InitialContext();
initialNamingContext.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
mi_iiop
set classpath=.;%classpath%
javac -d . Hello.java
javac -d . HelloImpl.java
rmic -iiop -d . jdeveloper.rmi_iiop.HelloImpl
這一步將生成<_Interface>_stub.class,<_InterfaceImpl>_Tie.class:
_Hello_Stub.class和_HelloImpl_Tie.class
2. 實現Client端程序
// HelloClient.java
package jdeveloper.rmi_iiop;
import java.rmi.RMISecurityManager;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.NotBoundException;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;
public class HelloClient {
public static void main(String args[]) throws Exception{
System.setSecurityManager(new RMISecurityManager());
Context initialNamingContext = new InitialContext();
Hello RemoteObj = (Hello) PortableRemoteObject.narrow(
initialNamingContext.lookup("iiop://"+ args[0] +"/HelloServer"),
Hello.class
);
System.out.println(RemoteObj.sayHello());
}
}
把HelloClient.java拷貝到目錄f:
mi_iiop中。
f:
cd
mi_iiop
javac -d . HelloClient.java
3. 運行程序
啟動DOS窗口
運行 tnameserv
把 server.bat 和 policy 放到f:
mi_iiop
啟動新的DOS窗口
運行 server
啟動新的DOS窗口
把 client.bat 放到f:
mi_iiop
運行 client hostname
server.bat
set CP=%classpath%
set classpath=.;%classpath%
java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
-Djava.naming.provider.url=iiop://hjc:900 -Djava.security.policy=policy jdeveloper.rmi_iiop.HelloImpl
set classpath=%CP%
client.bat
set CP=%classpath%
set classpath=.;%classpath%
java -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
-Djava.naming.provider.url=iiop://hjc:900 -Djava.security.policy=policy jdeveloper.rmi_iiop.HelloClient %1
set classpath=%CP%
policy
grant {
// Allow everything for now
permission java.security.AllPermission;