IDL总结idl入门

2023年 7月 19日 20.4k 0

IDL接口定义语言 参考: blog.csdn.net/gubenpeiyua…

一、什么是Java IDL

Java IDL(InterfaceDefinition Language)可实现网络上不同平台上的对象相互之间的交互,该技术基于通用对象请求代理体系结构CORBA规范说明。IDL是不依赖于语言的接口定义语言,所有支持CORBA的语言都有IDL到该语言的映射。就像其名字所表示的那样,Java IDL支持到Java语言的映射。CORBA规范说明和IDL映射是由OMG(ObjectManagement Group)定义的。OMG由700多个成员组成,Sun公司是其成员之一,它在定义IDL到Java映射的工作中起了主要作用。

JDK1.1给Java开发人员提供了开发100%纯Java分布式应用的功能,即远程方法调用Java RMI。而Java2平台提供的JavaIDL可以在分布式应用中使用非Java语言,也就是说,Java2平台提供的ORB(ObjectRequest Broker)可以和任何遵从CORBA规范的ORB互操作,包括IONAT echnologies的Orbix、Visigenic Software的Visi Broker、IBM的Component Broker等。目前,主要的Web浏览器(MicrosoftIE4.0和NetscapeNavigator4.0)实现的主要是JDK1.1中的功能。不过,利用Sun公司提供的Java插件(Plug-in)可以使浏览器具备Java2平台的所有特征。

需要说明的是,Java2平台提供了两种不同的方法来构造分布式应用系统,即Java RMI和Java IDL,它们具有相似的特征和功能,Java RMI支持用Java语言写的分布式对象,Java IDL可以与支持CORBA的任何程序设计语言如C、C++、COBOL等写的分布式对象交互。这两种方法各自具有不同的特点:

(1)100%纯Java和对遗产应用系统(legacy system)的支持。JavaRMI是对分布式应用系统的100%纯Java解决方法,具有Java的"Writeonce, run anywhere"的优点。用JavaRMI开发的应用系统可以部署在任何支持Java运行环境的平台上。

相反,JavaIDL是基于CORBA规范标准的技术,可以远程调用非Java语言编写的对象,因此Java IDL提供了对那些用非Java语言开发的遗产应用系统的支持。

(2)使用不同的通信协议。Java RMI和Java IDL目前使用不同的通信协议,Java IDL使用CORBA/IIOP协议,IIOP(InternetInter-ORBProtocol)协议可以使位于不同平台上、用不同语言写的对象以标准的方式进行通信;Java RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信,JRMP是专为Java的远程对象制定的协议,不过Sun和IBM已经宣布将来会支持在RMI中使用IIOP协议,以便和遵从CORBA规范的远程对象通信。

(3)通过引用调用对象还是通过值调用对象。在Java IDL中,客户端通过引用与远程对象交互,即客户机使用桩(Stub)对远程服务器上的对象进行操作,但并不拷贝服务器上的对象。

相反,RMI使得客户机可以通过引用和远程对象交互,也可以把远程对象下载到客户机运行环境进行操作,由于在RMI中使用的对象都是Java对象,因此RMI使用Java中的对象串行化(Serialization)功能在服务器和客户机之间传输对象。不过CORBA规范的以后版本将包括按值调用对象的功能。

Java RMI和JavaIDL各有自己的优缺点,从某种意义上说,RMI可以看作是RPC(Remote Procedure Calls)的面向对象版本。RMI的最大优势是可以用它来提供100%纯Java的解决方案,这意味着构造RMI应用系统将比较简单,但这也正是基于RMI的应用系统的一个缺点,即只能在Java环境中运行,不能充分利用遗产应用系统。

Java RMI和JavaIDL均可满足一定范围的用户需求,都适用于一定范围的应用,两者之间存在着重叠,有些应用可使用两者中的任何一种技术开发,但对于某些应用来说,采用其中的某一种比采用另一种更为恰当。

二、使用CORBA和JavaIDL

从1989年以来,OMG一直致力于开放的软件总线体系结构CORBA的规范说明的定义,利用CORBA,不同供应商开发的、运行在不同平台上的构件可以互操作,而不管该对象位于何处,用什么语言实现。Java IDL使得Java也支持CORBA规范说明。作为Java企业计算API的一部分,Java IDL可以保证企业异质计算中的无缝互操作性和可连接性。

CORBA对象和一般的程序设计语言中的对象的区别在于:

CORBA对象可以位于网络中的任何位置;

CORBA对象可以和其他平台上的对象交互;

CORBA对象可以用任何程序设计语言编写,只要有IDL到该语言的映射即可(目前已包括到Java、C++、C、Smalltalk、COBOL、Ada等语言的映射)。

接口定义语言IDL用于定义CORBA对象的接口,所有的CORBA对象都支持IDL接口。IDL语法和C++非常类似,利用Java IDL,可以在Java中定义、实现、存取CORBA对象。对于每个IDL,idl to java生成一个Java接口和其他一些必要的.java文件,包括一个客户端桩(Stub)和服务器端骨架(Skeleton)。

为了使用JavaIDL,需要有idl to java编译器,idl to java产生和任何遵从CORBA规范的ORB一起工作的客户端桩和服务器端骨架,Java2平台中包括CORBAAPI和ORB,使得Java应用系统通过IIOP协议可以调用远程的CORBA对象,JavaORB支持暂态(Transient)CORBA对象,提供了暂态名字服务器把对象组织成树目录结构,名字服务器遵从CORBA中COS规范说明的命名服务规范说明(Naming Service Specification)。

图1说明了从客户端到服务器发送一个消息请求的过程,其中客户端也可以是一个CORBA对象:

客户机不需要了解CORBA对象的位置与实现细节,也不需要了解哪个ORB用于存取对象。

在客户端,应用系统包括远程对象的引用,对象引用使用桩方法作为远程方法的代理,这个方法事实上在ORB中的,所以调用桩方法会调用ORB的连接功能,ORB会把对桩方法的调用传递到服务器端。

在服务器端,ORB利用骨架代码把远程调用转换成本地对象的方法调用,骨架需要对调用和参数的格式进行转换。同时,当方法返回时,骨架对结果进行变换,然后通过ORB把结果返回给客户机。

不同的ORB之间通过IIOP协议进行通信,IIOP是建立在TCP/IP之上的协议。

CORBA目前还处于发展阶段,一些标准还在定义之中,但CORBA中的大部分基本结构已经定义,许多软件供应商已根据CORBA的定义作了很多开发工作,Java IDL就是该规范说明的一个实现。但在Java2平台中,并没有实现CORBA规范说明中的所有特征,如:

接口库:在一般的Java IDL操作中并不需要接口库,Java客户机可以存取其他的接口库,如C++ORB提供的接口库;

RMI/IIOP协议;

按值调用对象;

IDL中的一些类型如wchar、wstring、longdouble等。

三、IDL到Java的映射

为了使Java支持CORBA规范说明,需要一个把IDL中的元素映射为Java中元素的标准途径,Sun已经制订了两者之间的映射规则,并提供了编译器idl to java,以便从IDL得到相应的桩和骨架。

下表列出了一些IDL中元素和Java中元素的映射关系。

和Java中的接口一样,IDL接口不包含方法的具体实现,Java开发人员需在Java类中提供对这些方法的具体实现。

四、使用Java IDL开发应用的过程及实例

用JavaIDL开发分布式应用系统一般可分为五个步骤:

1.定义远程接口

用IDL定义远程对象的接口,使用IDL而不是Java语言是因为idl to java编译器可以自动地从IDL产生Java语言的桩和骨架源文件,以及和ORB连接时所需要的一些代码。使用IDL,开发人员可以用其他语言来实现客户机和服务器。如果要为一个已经存在的CORBA服务实现客户机,或为一个已经存在的客户机实现服务,则首先要给出IDL接口,然后运行idl to java编译器产生桩和骨架,在此基础上再进行实现。

2.编译远程接口

在IDL文件运行idl to java编译器,产生Java版本的接口,以及桩和骨架代码文件,这些代码文件使得应用程序可以和ORB相连接。

3.实现服务器

把idlto java编译器产生的骨架和服务器应用程序集成在一起,除了要实现远程接口中的方法之外,服务器代码还要包括启动ORB以及等待远程客户机的调用等部分。

4.实现客户机

类似地,以桩作为客户端应用程序的基础,客户机建立在桩之上,通过Java IDL提供的名字服务查询服务器,获得远程对象的引用,然后调用远程对象中的方法。

5.启动应用程序

一旦实现了服务器和客户机,就可以启动名字服务,接着启动服务器,然后运行客户机。

下面以一个经典的HelloWorld程序来说明具体的开发过程。HelloWorld包含一个操作,该操作返回一个字符串并打印出来,Client和Server之间的通信过程如下:

(1)客户端应用程序或小应用程序调用HelloServer的sayHello操作;

(2)ORB把调用传递到已注册的服务对象;

(3)服务对象运行sayHello方法,返回一个Java字符串;

(4)ORB把该字符串返回给客户机;

(5)客户机打印该字符串的值。

尽管HelloWorld程序比较简单,但它涉及到的任务和几乎任何一个使用CORBA静态调用的分布式应用系统所涉及到任务相同,图2说明了如何用CORBA在客户机和服务器之间实现经典的"HelloWorld"程序。

首先是定义Hello.idl,下面是用IDL描述的Hello.idl,只有一个操作(方法),该操作返回一个字符串。

 Module Hello App
​
  {
 interface Hello
​
  {
 stringsay Hello ( );
​
  };
​
  };

然后把Hello.idl文件映射为Java源代码文件,用以下命令编译Hello.idl文件:

idl to javaHello.idl

根据命令行中的不同选项,idl to java编译器产生不同的文件,上面这条命令将创建子目录HelloApp并在其中产生五个文件:HelloImplBase.java、 HelloStub.java、Hello.java、HelloHelper.java、HelloHolder.java。

要完成该应用程序,还要分别在这五个文件的基础上提供服务器端和客户机端的实现。

CORBA服务器程序的结构和大部分Java应用程序的结构一样,即导入所需要的包,声明服务器类,定义main方法,处理一些例外等。另外,CORBA服务器要有一个ORB对象,每个服务器实例化一个ORB,并向其注册服务对象,因此当ORB接收到调用请求时可以寻找到服务器。最后是服务对象的管理,服务器是一个进程,实例化了一个或多个服务对象,服务对象具体实现接口中说明的操作。HelloServer和命名服务一起工作,使得服务对象对于客户机来说是可用的,服务器需要对名字服务的对象引用,可以向名字服务注册,并保证向Hello接口的调用被路由到其服务对象上,最后是等待客户机的调用。

CORBA客户机的结构和大部分Java应用程序的结构基本相似,即导入所需要的包、声明应用类、定义main方法、处理一些例外等。另外和服务器程序一样,一个CORBA客户机也需要本地的ORB来执行所有的配置工作,每个客户机实例化一个org.omg.CORBA.ORB对象,然后向该对象传递一些必要的信息以进行初始化,最后是利用ORB取得所需要的服务。一旦一个应用有了ORB,即可通过ORB来确定应用所需要的服务的位置,在本例子中即是Helloserver。为了调用CORBA对象中的操作,客户端应用要有对该对象的引用,有很多种方法可以得到这种引用,如调用ORB.resolve_initial_references或使用其他的CORBA对象(如命名服务),当在分布式环境中没有命名服务可用时,CORBA客户机使用字符串化对象引用(Stringifiedobjectreference)来得到其第一个对象。

1.4 接口定义语言(IDL)

一个IDL文件定义公共的应用程序接口(API),通过服务程序中的对象向外公布。一个CORBA对象的类型称作接口,与C++中的类或者Java中的接口类似。IDL接口支持多重继承。

一个IDL文件示例如图1.1所示。IDL接口可以包括方法和属性。很多人都误以为一个IDL接口的属性类似于C++中的示

例变量(或者Jave中的域)的概念。这是错误的。一个属性只是在语法上对一对儿get-和set-类型方法的称谓。属性可以是只读的,这种情况时该属性只有一个get-类型的方法。

module Finance {
   typedef sequence StringSeq;
​
   struct AccountDetails {
   string name;
​
   StringSeq address;
​
   long account number;
​
   double current balance;
​
    };
​
   exception insufficientFunds { };
​
   interface Account {
       void deposit(in double amount);
​
       void withdraw(in double amount)
    
           raises(insufficientFunds);
    
       readonly attribute AccountDetails details;
    
    };
​
};

图1.1: IDL文件示例

方法的参数有一个指定的方向,可以是in(意味着参数由客户程序传入服务程序),out(参数从服务程序传回客户程序)或者inout(参数是双向传递的)。方法同样可以有返回值。方法在某块出错时可以引发(抛出)一个异常。有30多种预定义的异常类型,称作系统异常,他们都可以由方法抛出,尽管在实际系统中CORBA运行时系统引发的异常多于应用程序代码引发的。除了预定义的系统异常,新的异常类型可以在IDL文件中定义,这些异常可称为用户定义的异常。方法署名的raises子句指定该方法可能抛出的用户定义异常。

方法的参数(包括返回值)可以是内置类型的一种——例如:string,boolean或者long,也可以是IDL文件中定义的用户自定义的类型。用户定义类型可以是一下的任意一种:

结构体。类似于C/C++中的结构体或者Java中只包含公共域的类。

序列。集合类型,就像一个可以增或减的一维数组。

数组。IDL数组的维度在IDL文件中指定,所以数组是固定大小的,这就是说他不能在运行时增或者减。数组在IDL中很少用到。序列类型更灵活,所以用的更多。

自定义。给现存的类型定义一个新名字。例如,下面的语句定义age可用来描述short。

typedef short age;

默认情况下,IDL的序列和数组是匿名类型,也就是说他们没有名字。通常使用typedef的重要意义在于给序列或者数组的声明关联一个名字。例句可以在图1.1中StringSeq的定义中看到。

联合体。该类型可以在运行时保留多个值中的一个。例如:

union Foo switch(short) {
   case 1: boolean boolVal;
​
   case 2: long longVal;
​
   case 3: string stringVal;
​
};

一个Foo类型的实例可以保存一个boolean、long或者string值。前面的case标记(成为判别式)表明当前是哪种值。与IDL联合体相同的理念可以在很多面向过程的语言中找到。但是,他们很少在面向对象的语言中使用,因为多态统称能以更好的方式达到同样的目的。

枚举类型。枚举在概念上类似于一个常整型集合的声明。例如:

enum color (red, green, blue );

enum city (Dublin, London, Paris, Rome );

从本质上说,CORBA使用整数表达不同的枚举值,使用枚举声明的好处在于很多编程语言都有对它的内在支持,或者相似的机制,可以用来进行强类型判识,这样程序员就不会将city变量和color变量相加。

定点类型。定点类型保存定点数值,而float和double类型保存浮点数值。浮点计算适用于很多用途,但是,可能导致几个小数位后的舍入误差。对比来说,定点数值可能比对应的浮点数值占用更多的内存空间,但是他们有避免舍入误差的优点。使用定点数值趋向于限制在适当的应用领域。例如金融计算和数字信号处理等。尽管一个工程使用定点类型数字,它很可能使用定点计算作为细节实现却不将定点数字的使用公布为公共的IDL接口。由于以上原因,定点类型很少在IDL文件中声明。

值类型。在9.2节、96页讨论。

IDL类型可以组织在一个module中。module结构与C++中的namespace或者Java中的package有异曲同工之妙,也就是说,他事先给类型名称前添加了一个前缀,以避免命名空间冲突。IDL中的域操作符是“::”。例如,

Finance::Account是Finace模块中定义的Account类型的全域名

编译 IDL 后生成的 Java 类

Helper

为接口客户提供有用的助手功能的类。编译器为 narrow 功能自动生成代码,这种 narrow 功能让客户将CORBA对象引用强制转换为接口类型。还提供了绑定(bind)功能,用户可以用其查找该类型的对象。

Holder

含有接口类型的公共实例成员的类。用户和服务器用其来以方法调用的 out 和 inout 参数的形式传递接口类型的对象

Stub

为接口对象实现客户端存根的类,它是真正的提供排列功能的接口的内部实现。

Operations

定义了 IDL 功能的类。

Tie

CORBA支持两种类型的程序:基于继承(inheritance-based)的和基于委托的(delegantion-based)。Tie类只是扩展了POA,但它没有提供自己的实现语义。它把所有的工作委托到一个实现对象上。每一个Tie对象存储一个实现对象的引用。

委托方法可用两种类实现IDL接口:1.一个IDL生成的Tie类,该类继承自POA,但是委托所有的调用到一个实现类;2.一个实现IDL生成的Operations接口的类,它定义了IDL的功能。

POA

为接口实现CORBA服务器端框架的类。这个类将 CORBA 和 Java 对象模型组合到一起。它是通过使用一个实现了Java的org.omg.CORBA.Object接口的 Java 对象做到这一点的。这是CORBA根接口,所有得CORBA对象都必须实现它。

CORBA IDL-to-Java 映射

通用结构:

1.CORBA模块

ORBA IDL 模块(module)映射成与IDL模块同名的Java包

2.CORBA异常

CORBA定义了两类异常

I.system exceptions 一种被CORBA定义的异常

II.user-defined exceptions 由用户在IDl中定义的异常

3.CORBA 参数

CORBA定义了三种参数传递模式:in、out和 inout。Java 只支持in 。

4.CORBAHolder 类

由于Java中没有IDLout 和 inout 的对应物,对IDL out 和inout 参数,IDL-to-Java 映射必须提供一些附加的机制来支持值传递(并返回结果)。

映射定义 Holder 类,这些 Holder 类在Java中实现附加的参数传递模式。对每个IDL out 或 inout 参数,客户必须实例化一个适当的 Holder 类的实例(它是通过值传递的)。

5.CORBAHelper 类

Helper 类包含用于不同方式操作IDL的方法。

Helper 类提供客户可以用来操作类型的静态方法,这些包括该类型的任何插入和取出操作、获得库(repository)ID、获得类型码(typecode)、从流中读取类型并把类型写入流中。

另外,映射IDL接口的Helper类提供一个静态的narrow方法,可以用于进行强制类型转换。

6.CORBA属性

CORBA IDL 接口可以拥有属性,这些都是类型域中set和get操作所需的。

每个属性都被映射到一对与属性同名的重载Java访问器和修改器方法上。

结构类型:

1.sequence(序列)

一个可变大小的一维元素序列,其中元素可以是任何IDL定义的类型。可以限制序列的最大长度。

2.struct(结构)

可以使用结构将多种类型的命名字段组装在一起

每个struct都有两个构造函数。一个是默认的构造函数,把结构中的所有字段设置为空。第二个构造函数把结构字段作为参数并初始化每个字段

3.union(联合)

用于在任何给定的时间只引用几个数据成员中的一个(任何时间,内存中只能有一个成员)。联合使用discriminator标签值来显示该值含有联合中的那个成员。

  • Any
  • Any是一个保留其类型的自描述数据结构,它使你可以在运行时用类型安全的转换函数提取和插入预定义的IDL类型的值。

    Any类型让你指定一个属性值、参数或返回类型,该类型包含一个在运行时而不是在编译时确定的任意类型。可以使用Any传递任何东西。

    IDL-to-Java 的映射

    www.ibm.com/developerwo…

    www.ibm.com/developerwo…

    Java IDL

    www.iplab.is.tsukuba.ac.jp/~liuxj/jdk1…

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论