本文翻译自:
Getting Started with Java IDL
Java IDL是一种分布式对象的技术:使对象可以通过网路和不同的平台交互。Java IDL可以让对象在不同的语言中交互,如:C, C++, COBOL...
Java IDL实现这一功能通过公共对象请求代理体系结构(CORBA)—一种分布式对象模型行业标准。CORBA的关键特征是IDL(一种无依赖接口定义语言)。每种语言都自己实现了IDL来支持CORBA。Java的语法映射详见Java IDL: Mapping IDL to Java
Java IDL提供了ORB(对象请求代理)来支持分散的程序中的对象之间的交互。ORB是一个类库,实现了Java IDL应用和其它支持CORBA应用之间的底层通信。
这篇教程讲述使用Java IDL构建CORBA分布式应用所需的基本技能。你将实现一个经典的“Hello World”分布式应用。
每两个分布式对象的关系中间有两个部分:客服端和服务端。服务端提供远程接口,客户端去调用这个远程接口。这是包括Java Remote Method Invocation(RMI,RMI-IIOP)和CORBA等大多数分布式对象标准中比较常见的方式。
下图表示了在实现“Hello World”中,一个方法的分布式对象是怎么样在CORBA客户端和服务端怎样被共享的。
在客户端,应用有一个远程对象的参照(reference)。这个Object Reference有个能被远程调用的存根(stub)方法的替身。存根实际是连接ORB的,所以调用它就是会使ORB的连接服务端发起调用。
在服务端,ORB使用skeleton code翻译处理远程调用命令后调用本地对象。skeleton翻译调用和参数成可以调用的格式然后开始调用方法。当调用返回,skeleton会把报错或结果打包翻译并通过ORB送回给客户端。
在两个ORB之间,通信由多个共享的协议,IIOP(the internet inter-ORB Portocaol)处理。IIOP是基于TCP/IP协议标准的一种标准来定义CORBA风格的ORB之间怎样输送和接收信息的。例如CORBA和IDL,IIOP标准被定义成OMG(the Object Management Group)。
Java IDL开发过程和Hello World教程
1. 定义远程接口
使用OMG的IDL定义你的远程对象的接口。不用Java而用IDL的原因是idlj编译器自动从IDL中 生成Java的stub和skeleton源文件,以及连接ORB的基础代码。同时,你能让他人实现客户端和服务端在别的CORBA风格语言中。
注意,如果你要实现一个已经存在的CORBA服务的客户端或者已经存在的客户端的服务端,你需要从实现者那取得IDL接口。然后用idlj编译器编译这些接口和余下的步骤
//Hello.idl
module HellpApp
{
interface Hello
{
string sayHello();
oneway void shutdown();
};
};
2. 编译远程接口
当你用idlj编译后,会生成Java接口文件和stubs和skeletons能让你的应用连接入ORB。
idlj编译器默认只生成客户端的绑定。如果你需要绑定客户端和服务端的skeletons,你得在运行idlj编译时使用 -fall 选项,更多idlj选项(Solaris, Linux, or Mac OS X or Windows)
$idlj -fall Hello.idl
3. 实现服务端
完成编译后,你能用skeletons把服务端应用结合。除了实现远程接口的方法之外,你的服务端代码包括了ORB启动和等待客户端调用的机制。
// HelloServer.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;
import java.util.Properties;
class HelloImpl extends HelloPOA {
private ORB orb;
public void setORB(ORB orb_val) {
orb = orb_val;
}
// implement sayHello() method
public String sayHello() {
return "\nHello world !!\n";
}
// implement shutdown() method
public void shutdown() {
orb.shutdown(false);
}
}
public class HelloServer {
public static void main(String args[]) {
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// get reference to rootpoa and activate the POAManager
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
// create servant and register it with the ORB
HelloImpl helloImpl = new HelloImpl();
helloImpl.setORB(orb);
// get object reference from the servant
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
Hello href = HelloHelper.narrow(ref);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
// Use NamingContextExt which is part of the Interoperable
// Naming Service (INS) specification.
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// bind the Object Reference in Naming
String name = "Hello";
NameComponent path[] = ncRef.to_name( name );
ncRef.rebind(path, href);
System.out.println("HelloServer ready and waiting ...");
// wait for invocations from clients
orb.run();
}
catch (Exception e) {
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
System.out.println("HelloServer Exiting ...");
}
}
// 编译.java
$javac HelloServer.java HelloApp/*.java
4. 实现客户端
同样,利用idlj编译生成的stubs完成你的代码。
//HelloClient.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class HelloClient
{
static Hello helloImpl;
public static void main(String args[])
{
try{
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// get the root naming context
org.omg.CORBA.Object objRef =
orb.resolve_initial_references("NameService");
// Use NamingContextExt instead of NamingContext. This is
// part of the Interoperable naming Service.
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
// resolve the Object Reference in Naming
String name = "Hello";
helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));
System.out.println("Obtained a handle on server object: " + helloImpl);
System.out.println(helloImpl.sayHello());
helloImpl.shutdown();
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
}
}
}
// 编译
$javac HelloClient.java HelloApp/*.java
5. 启动你的应用
启动你的服务后,启动服务端和客户端。
// start orbd
// in Solaris, Linux, or Mac OS X command shell
$orbd -ORBInitialPort 1050 -ORBInitialHost localhost&
// MS-DOS system prompt (Windows)
$start orbd -ORBInitialPort 1050 -ORBInitialHost localhost
// start the hello server
// shell
$java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost&
// MS-DOS
$start java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost
// run the client application
java HelloClient -ORBInitialPort 1050 -ORBInitialHost localhost