6 月份,我们谈过您为什么要使用 CORBA 和 Java 技术。本月,我要通过一个可用的简单示例,让您开始探索 CORBA 技术的许多领域。不过,别忘了我们的目标是,创建这样一种分布式应用程序:使驻留在一台计算机上的客户机能向运行于另一台计算机上的服务发出请求。我们不想为诸如硬件或操作系统软件等细节问题操心,而只是想让这种服务能响应客户机的请求。
IDL 接口
全部 CORBA 结构是从一个接口开始的,理解接口的最佳方法就是想像我的汽车,对,我的汽车。虽然您不熟悉它,但假如我对您说:“开上我的车,带些三明治回来当午餐”,恐怕您就不会怀疑自己能不能驾驶我的汽车。您可能想知道它停在哪里,以及开它是否安全,但是您会确信开我的车与开您的车差别不大。这是因为,在各种汽车当中,人与汽车之间的接口已高度标准化了。我的轿车和您的跑车之间可能会有一些差异,但汽车的油门踏板、刹车和方向盘的安装都是标准的,您一定能轻松快速上路。
因为 CORBA 与语言无关,所以它依靠一种接口定义语言 (IDL),来表达客户机如何向实现接口的服务发出请求。我们的接口就是一个方法:add()。这个方法将取两个数(两个 IDL 的 long 型数)并返回这两个数之和。下面是我们的接口计算程序:
清单 1. calcsimpl.idl
module corbasem {
module gen {
module calcsimpl {
interface calculator {
long add(in long x, in long y);
};
};
};
};
这个接口中的 IDL 要害字有:module、interface、long 和 in。IDL 使用要害字 module 来创建名称空间,并且此要害字准确地映射为 Java 要害字 package。运行 IDL-to-Java 编译器时,生成的 Java 文件将会存到名为 calcsimpl 的子目录中。IDL 要害字 interface 完美地映射为 Java 接口,并代表一种抽象类型,因为两者都只定义您与对象通讯的方式,而不涉及对象的实现。IDL 要害字 long 是一种基本的整数类型,它至少映射为一个 4 字节的类型,这种类型在 Java 代码中就是 int。
想一想执行远程方法调用的机制,您就会发现定义参数传递的方向(客户机到服务器、服务器到客户机或者双向传递)是多么的有意义。在 IDL 操作中,这些方向用 in、out 和 inout 要害字来声明,每个参数都必须声明方向,以便使对象请求代理程序 (ORB) 知道该参数的去向。这会影响到为发送而进行的参数打包、参数解包以及内存治理。ORB 对参数了解得越多,它的效率就越高。要害字 in 表明 long x 和 long y 是从客户机传递到服务器。
图 1. 参与 CORBA 请求的各个部分
IDL 编译器 需要 IDL 编译器吗?
您可能已经有了 ORB 供给商和 IDL-to-Java 编译器。但假如还没有,您从哪里获取呢?这里有好多,而且有些还可以免费下载。我推荐 Object Oriented Concepts, Inc. 的 Orbacus ORB。假如不将其用于商业目的,它还可以免费下载,而且完全符合 CORBA 2.3 规范。另外一个可试用 60 天的编译器是 Inprise 的 Visibroker,也完全符合 CORBA 2.3 规范并且可下载。如想获得这两种产品,请参阅参考资料。
接口定义以后,必须在 ORB 供给商提供的 IDL-to-Java 编译器上运行。IDL 编译器是一种精巧的实用程序,它生成 IDL 的 stub 和 skeleton 以及其它支持文件。生成的这些源文件,大部分将增强 CORBA 标准中定义的特定 IDL 类型的打包功能。编译器将生成大部分网络探测 (plumbing),这在分布式系统中非常重要。在最基本的级别中,IDL-to-Java 编译器只是一个按 CORBA 2.3 规范的定义来实现从 IDL 到 Java 语言映射的程序。手动生成这些代码既枯燥又费时,还轻易出错;IDL-to-Java 编译器会处理这一切,所以您就不用操心啦;同时,它会用一定的规则约束您,并强制您执行封装。IDL-to-Java 编译器将把 CORBA-land 规则强加给您的系统。
输入下面的命令,从 Orbacus 执行 IDL-to-Java 编译器,把所有生成的文件都放在 CLASSPATH 的输出目录下。
清单 2. 调用 IDL-to-Java 编译器 jidl --output-dir c:\_work\corbasem calculator.idl
生成了什么呢?这个命令生成了构建实现所需要的全部 Java 源文件。IDL-to-Java 编译器可确保所定义的接口遵守 CORBA 规范的规则。