5.3 corba技术及实例
corba是一种规范,它定义了分布式对象如何实现互操作。在worldwideweb盛行之前,特别是java编程语言风靡之前,c++开发者基本将corba作为其高端分布式对象的解决方案。
实际的corba规范归对象管理组(objeotmanagementgroup)管辖,这是一家由700多家公司组成的开放的研讨会,其工作是制订对象计算的开放标准。corba对象可以用任何一种corba软件开发商所支持的语言,如c、c++、java、ada和smalltalk,来编写。同样地,corba对象可以运行在任何一种corba软件开发商所支持的平台上,如solaris,windows95/nt,openvms、digitalunix、hp-ux或aix等。这意味着,我们可以在windows95下运行java应用程序,同时动态调入并使用c++对象,而实际上,该对象可能存储于一个在internet上的unixweb服务器上。
使用 接口描述语言(interfacedescriptionlanguage)编写的对象接口,使得与语言无关的独立性成为可能。idl使得所有corba对象以一种方式被描述,仅仅需要一个由本地语言(c/c++、corba、java)到idl的“桥梁”。corba对象的互通信要以对象请求解析器(object request broker)为中介,这种互通可以在多种流行通信协议之上(如tcp/ip或是ipx/spx)实现。在tcp/ip上,来自于不同开发商的orb用internetinter-orb协议(iiop)进行通讯,这是corba2.0标准(最新的版本)的一部分。
目前,对于较为流行的编程语言(包括c++,smalltalk,java和ada95),已经有了许多第三方的orb。随着其他语言的逐渐流行,corba开发商毫无疑问地要做出相应的orb来支持它们。
5.3.1 corba简介
最初,omg在1990年制订了对象管理体系(objectmanagementarchitecture),即oma,来描述应用程序如何实现互操作。作为其中的一部分,需要有一个标准规范应用程序片段即对象的互操作──这导致了corba的诞生。oma定义了组成corba的四个主要部分。(图1.1)
图1.1 omg的corba参考模型
l object request broker,orb作为对象互通讯的软总线。
l object services,定义加入orb的系统级服务,如安全性、命名和事务处理。
l common facilities定义应用程序级服务,如复合文档等。
l application interface 定义现实世界的对象和应用,如飞机或银行帐户。
1.objectrequestbroker详述
oma最重要的部分就是orb。为了创建一个遵从corba规范的应用程序,orb是corba四大部分中唯一必须提供的。许多orb版本根本不带corbaservices或是corbafacilities,你可以自制(或购买)商用对象。但是,没有orb,corba应用程序绝对无法工作。(图5.2)
图5-.2 单个orb的体系结构
corb orb最显见的功能,是对你的应用程序或是其它orb的请求予以响应。在corba应用程序运行期间,你的orb可能被请求做许多不同的事情,包括:
l 查找并调用远程计算机上的对象
l 负责不同编程语言之间的参数转换(如c++到java)
l 可超越本机界限的安全管理
l 为其它的orb收集并发布本地对象的metadata
l 用下载的代码(stub)中描述的静态方法调用去击活远程对象中的方法
l 用动态方法调用击活远程对象
l 自动击活一个当前没有装入内存运行的对象。
l 将回调方法导引向其管理之下的本地对象
实现细节对软件开发者的透明性,是orb的一个杰出的特性。用户只须在代码中提供相应的hooks,用于初始化orb并向orb登记该应用程序,就可以将该应用程序和大量分布式对象建立联系。
2.用idl描述对象
为了保持corba的商业中立性和语言中立性,必须有一个中介,存在于象c++corba服务器代码和javacorba客户机这样的实体之间。这就是idl。一个底层对象的若干相关方法和属性被idl集入一个单一接口。一旦idl接口定义完成,它可以以stub码或框架代码(skeletoncode)的形式编译成你选用的语言。在所有的orb中都有idl编译器。例如,visigenicvisibrokerforjavaorb中就含有java/idl编译器,而visigenicvisibrokerforc++orb则提供了c++/idl编译器。
有一点值得注意的是idl不同于其它的面向对象程序设计语言,我们不能用它指定它所定义的类或是方法的具体实现。因此,将它仅仅作为一种定义底层对象接口的语言要好得多。
就象在java中将属性和方法封装到相关的类中一样,上述各项均包含在idl的模块之中。在一个模块之中可以定义一个或多个接口。表一中的简单idl模块名为themodule,它含有一个称为theinterface的基本接口。该接口仅有一个定义为整型的简单变量(即thevariable)。
5.3.2 用java做corba开发实例
为了创建一个分布式的java小应用,并让它用corba访问服务器对象,我们利用一个流行的商用orb,并用idl定义对象接口。在示例小应用中,我们选用了visigenic visibroker for java。这种orb已经经过oracle、netscape和novell等公司的认证,并已被纳入netscapenavigator4.0。
注意:你可以在非netscapenavigator4.0的浏览器中运行这个小应用。由于它首先要从别处下载一些java类文件,启动速度可能会稍慢一些。
我们将用一个简单的java小应用调用一个使用corba的服务器对象。为简单起见,同样用java书写服务器对象。该服务器对象用一个数组存储有关各种corbaorb开发商及他们产品的信息。客户小应用将调用该对象并查询数组。一个更为完整的例子(仔细思考一下)是将orb信息存储于关系数据库中,利用jdbc(或是别的数据库访问方法)获得相关信息。这种方法将用corba生成一个真正的三层应用程序。
1.最简单的idl模块
module themodule
{
interface theinterface
{
long thevariable;
};
};
如果你用一个idl到java的编译器编译这个idl模块(如visigenic的idl2java),就会得到表1-2中的java接口。
表1-2与themodule相应的java代码
package themodule;
public interface theinterface
{
public int thevariable;
}
2.orbquery小应用
这个客户端的小应用含有标准的javagui,并将调用一个远程corba对象。一旦该对象被调用,就可以使用其方法获得某一指定corba orb的信息。在服务器端,为了获得特定orb的如下信息:名称(name)、销售商(vendor)、操作系统(operatingsystem)、语言(languages)和url,我们必须定义五个方法。因此,必须在idl接口中定义这五种方法才能获取相应信息。表1-3定义了这个名为orbinfo的接口:
表1-3:orbinfoidl界面
module orbquery
{
interface orbinfo
{
string getname(in long index);
string getvendor(in long index);
string getos(in long index);
string getlanguages(in long index);
string geturl(in long index);
};
};visibroker安装中含有一个idl编译器──idl2java,你可以用它生成实现该接口必需的java代码。软件安装完成之后,只要执行如下命令即可生成代码:
idl2javaorbinfo.idl
这步操作将创建一个名为orbquery的子目录(与orbqueryjava包相对应)。在该目录内有8个文件:orbinfo.java,orbinfoholder.java、orbinfohelper.java、_st_orbinfo.java,_sk_orbinfo.java、orbinfooperations.java、_tie_orbinfo.java和_example_orbinfo.java。你可能已经猜到,orbinfo.java文件含有定义orbinfo接口的java源文件,但其它的java类又怎样呢?
orbinfoholder.java文件内含有一个传递参数时使用的主类(holderclass),而orbinfo-helper类则定义了各种实用函数。_st_orbinfo类定义了客户stub,_sk_orbinfo定义了服务器框架类(skeletonclass)。
orbinfooperations和_tie_orbinfo类用于实现一种捆绑机制,这是visibroker的一个特性,它使得实现类能够继承框架类之外的类。在示例中,我们不会直接使用这几个类。最后,_example_orbinfo含有一个示例服务器对象,对它加以扩展就可创建一个服务器应用程序。
通过idl编译器生成的这八个java类,我们可以构建一个框架,由一个接口(interface)、一个stub、一个skeleton和几个帮助类,我们可以用java创建自己的客户机/服务器模式的corba应用程序。
3.创建服务器应用程序
下面,我们需要创建一个向服务器orb登记orbinfo对象的服务器应用程序。这个新对象将扩充框架类(skeletonclass)并实现orbinfo接口。因此,该服务器共需两个新类:一个用于定义服务器对象并实现orbinfo接口,另一个向服务器orb登记该对象。orbquery类包含的标准java代码负责取回数组中的指定元素。server类中含有corba特有的功能。
接下来的例子中,开始是初始化orb。然后,用“orbinfo”字符串向orb登记类,客户机利用这个字符串检索一个对象。所有的操作完成后,调用boa.obj_is_ready(),通知orb一切准备就绪。
表1-4是server类,它向orb登记了orbinfo对象。
表1-4 服务器类
public class server {
public static void main(string[] args) {
try {
// initialize the orb.
org.omg.corba.orb orb = org.omg.corba.orb.init();
// initialize the boa.
org.omg.corba.boa boa = orb.boa_init();
// create the orbquery.
orbquery serverquery = new orbquery("orbinfo");
// export the newly create object.
boa.obj_is_ready(serverquery);
system.out.println(serverquery + " is ready.");
// wait for incoming requests
boa.impl_is_ready();
}
catch(org.omg.corba.systemexception e) {
system.err.println(e);
}
}
}
表1-5给出了orbquery类,它实现了接口及五个帮助方法。
表1-5:orbquery类
import java.util.*;
class orbquery extends orbquery._sk_orbinfo {
string[][] orbvendors =
{{"powerbroker","orbix","visibroker","componentbroker","
solaris neo"},
{"expersoft corp.","iona technologies","visigenic software",
"ibm","sun"},
{"ole and activex bridges; windows95/nt;
solaris; hp-ux; aix; jdk 1.0.2",
"windows95/nt, mvs, os/2, qnx, vxworks, solaris, hp-ux,
irix, aix, digital unix, ole bridge",
"windows95/nt, sun os, solaris, hp-ux, aix, irix",
"windows95/nt, solaris, hp-ux, aix, os/390, os/2, as/400",
"solaris (client & server), windows95/nt (client), jdk 1.0.2"},
{"c++, java", "java, smalltalk, ada95, c++", "java, c++",
"java, c++", "java, c++"},
{"http://www.expersoft.com", "http://www.iona.com",
"http://www.visigenic.com",
"http://www.software.ibm.com/ad/cb", "http://www.sun.com/solaris/neo/solaris_neo/index.html"}};
orbquery(string name) {
super(name);
}
public java.lang.string getname(int index)
{
string name;
name = orbvendors[index][0];
return name;
}
public java.lang.string getvendor(int index)
{
string vendor;
vendor = orbvendors[index][1];
return vendor;
}
public java.lang.string getos(int index)
{
string os;
os = orbvendors[index][2];
return os;
}
public java.lang.string getlanguages(int index)
{
string languages;
languages = orbvendors[index][3];
return languages;
}
public java.lang.string geturl(int index)
{
string url;
url = orbvendors[index][4];
return url;
}
}
至此,我们已经写好了所有服务器方必需的代码,下一步的工作是创建客户小应用,初始化客户orb,进而击活并调用刚刚生成的服务器对象。
4.创建corba小应用
正如服务器对象要向服务器orb登记一样,客户端小应用或应用程序需要向客户机orb登记。当要获得远程corba对象时,客户机采用了一种间接的方法,它通知客户机orb其意图,由orb负责orb到orb的通讯。这种请求方式由下面两行代码实现(在visibrokerforjava中):
//初始化orb(使用applet)
org.omg.corba.orborb=org.omg.corba.orb.init(this);
//检索applet要调用的orbinfo接口对象
orbinfoquery=orbquery.orbinfohelper.bind(orb,"orbinfo");
执行了bind()方法调用之后,我们的orbinfoquery本地变量与服务器的orbinfo对象绑在一起。这一操作完成之后,我们就可以调用帮助方法来实现客户端小应用。记住,尽管示例中我们完全使用了java语言,但实际上,服务器对象也可以用其他语言来实现,如:cobol、c++、ada和smalltalk。
5.编写简单的corba服务的一般流程
(以java2为例):
l 编写所需要的接口idl文件。
n foo.idl
module foo{
interface function{
float square_root(in float number);
}
}
l 用idltojava编译idl文件。
n idltojava –fno-cpp foo.idl
l 用javac编译所产生的类。
n javac ~\*.java
l 生成实现类。
n (functions.java) functinosimpl.java
l 生成实现服务器。
n fooserver.java
l 生成客户机应用程序(或小程序)。
n fooclient.java
l 编译实现服务器和客户机代码。
n javac functionsimpl.java fooserver.java fooclient.java
l 启动命名服务应用程序tnameserv。
n tnameserv –orbinitialport 1080
l 启动服务器(用命名服务注册)。
n java fooserver –orbinitialport 1080
l 启动客户机。
n java fooclient –orbinitialport 1080
6.结论
与单纯的java小应用相比,创建corbajava应用稍显复杂。事实上,这同样比用rmi创建纯粹的java分布式对象应用要难一些。但是,corba和java的联合,所创建的应用程序功能更为强大,更具可扩充性,这是单纯用jdk开发所无法比拟的。另外,现实是企业界很少使用java应用程序。corba是两全其美的选择,一方面它允许开发者利用已有的代码保护投资,另一方面又可以充分发挥java编程语言的优势。
5.4 jsp与corba技术的结合使用
若想实现web上分布式客户机/服务器模式的应用程序,可以选择多种不同的技术。但是,对于必须服务于大量用户的应用,我们认为应该首选corba,因为它具有可扩展性和业界广泛的支持。由于corba的强健性可以提高java编程语言的性能,利用已有的基于标准的技术,java开发者可以编写出功能强大的web应用程序。
想要对已有的web软件资源加以利用,或是编写真正功能强大的应用程序,使internet/intranet成为通信主干,所使用的技术必须具有以下特性:
· 支持现有的c、c++和cobol代码
· 支持java,以建立具有可移值性、平台独立性的面向对象的应用程序
· 商业中立性,只有这样,应用程序才易于维护,且不会被时间淘汰。
· 可扩充性,能够支持大量用户
· 它应该被多种平台所支持,而不是固定于某种平台之上。
· 开发模型应该是面向对象的(因为oop有许多固有优势)
· 端到端的安全性
· 广泛的业界支持
这种技术便是以corba为最佳。
servlets是java 2.0中新增的一个全新功能,它是运行在请求/面向请求服务器上的模块,比如一个java-enabled web 服务器, 和类似这样的延伸场合. 例如, 一个servlet可以从一个html订单表中获取数据然后用一些商业上的算法来更新公司相应的订单数据库。
也就是说:servlet能够象cgi脚本一样扩展web服务器功能,但是servlet占用很少密集资源,有很多用cgi脚本编制的一些站点由于访问量剧增,性能迅速下降,这是cgi脚本一个缺点。同时由于servlet是用java编写的,因此是跨平台的。可以这样说,实际servlet是电子商务真正的开始。
跨平台的java servlet与跨语言的corba的强强联合,使得开发者可以编写出功能强大的web应用程序。
