JacORB1.4 编程指南


JacORB1.4 编程指南编程指南编程指南编程指南 中文翻译:hlstudio(hlstudio@sina.com) ,cocia(cocia@163.com)(第 7 章) 校稿:allen(allen@huihoo.com),fat1(xwcheng@sina.com) 2002.08 2 目录目录目录目录 1 前言 ............................................................................................................................................4 2 安装 JacORB..............................................................................................................................5 2.1 获取 JacORB............................................................................................................................5 2.2 安装 JacORB.............................................................................................................................5 2.2.1 Ant 和 build.xml................................................................................................................5 2.2.2 配置 ..................................................................................................................................5 3 编程起步 ....................................................................................................................................9 3.1 JacORB 开发步骤.....................................................................................................................9 3.2 IDL 接口定义 ...........................................................................................................................9 3.3 生成 Java 类...........................................................................................................................10 3.4 实现接口................................................................................................................................10 3.5 编写服务器............................................................................................................................11 3.6 编写客户端............................................................................................................................12 3.7 桥接方式................................................................................................................................13 4 JacORB 命名服务....................................................................................................................15 4.1 运行命名服务........................................................................................................................15 4.2 访问命名服务........................................................................................................................16 4.3 构造层次命名空间................................................................................................................16 4.4 命名管理器............................................................................................................................16 5 服务端:POA 及线程 .............................................................................................................18 5.1 POA.........................................................................................................................................18 5.2 线程........................................................................................................................................18 6 实现仓库 ..................................................................................................................................19 6.1 概述........................................................................................................................................19 6.2 使用 JacORB 的实现仓库.....................................................................................................19 6.3 服务迁移................................................................................................................................20 6.4 安全考虑................................................................................................................................21 7 Any Value 的动态管理............................................................................................................22 7.1 概述........................................................................................................................................22 7.2 接口 ........................................................................................................................................22 7.3 用法限制................................................................................................................................22 7.4 创建一个 DynAny 对象........................................................................................................23 7.5 访问 DynAny 对象的值........................................................................................................24 7.6 传送 DynAny 对象的值........................................................................................................24 7.7 构造类型................................................................................................................................25 7.7.1 DynEnum.........................................................................................................................25 7.7.2 DynStruct.........................................................................................................................25 7.7.3 DynUnion ........................................................................................................................25 7.7.4 DynSequence...................................................................................................................25 7.7.5 DynArray.........................................................................................................................25 7.8 Any 和 DnyAny 对象之间的转换 .........................................................................................26 7.9 更多例子................................................................................................................................26 8 接口仓库 ..................................................................................................................................27 8.1 接口仓库中的类型信息........................................................................................................27 3 8.2 接口仓库设计.........................................................................................................................27 8.3 使用接口仓库........................................................................................................................28 9 JacORB 的小程序代理............................................................................................................30 9.1 使用小程序代理....................................................................................................................30 9.1.1 使用步骤 ........................................................................................................................30 9.1.2 程序属性 ........................................................................................................................30 9.1.3 小程序代理和 Netscpe/IE,AppletViewer...................................................................31 9.1.4 示例 .................................................................................................................................31 9.2 通过防火墙使用 JacORB......................................................................................................31 9.2.1 小程序代理 ....................................................................................................................31 9.2.2 HTTP 隧道 ......................................................................................................................32 9.2.3 小程序代理和 HTTP 隧道 ............................................................................................32 9.2.4 总结 ................................................................................................................................32 10 基于 SSL 的 IIOP.....................................................................................................................33 10.1 重编译 JacORB 安全库.......................................................................................................33 10.2 配置 IAIK ............................................................................................................................33 10.2.1 设置 IAIK 证书库........................................................................................................33 10.2.2 一步一步生成证书 ......................................................................................................35 10.3 配置 SSL 的属性.................................................................................................................35 10.3.1 客户端配置 ..................................................................................................................36 10.3.2 服务器端配置 ..............................................................................................................36 11 双向 GIOP................................................................................................................................37 11.1 设置双向 GIOP....................................................................................................................37 11.1.1 设置 ORB 初始属性....................................................................................................37 11.1.2 创建双向策略 ..............................................................................................................37 11.2 验证双向 GIOP 已经使用...................................................................................................37 11.3 TAO 协同性..........................................................................................................................38 12 可移植拦截器-PI .....................................................................................................................39 13 JacORB 实用程序....................................................................................................................40 13.1 IDL ........................................................................................................................................40 13.2 ns ...........................................................................................................................................40 13.3 nmg........................................................................................................................................41 13.4 lsns.........................................................................................................................................41 13.5 dior ........................................................................................................................................41 13.6 pingo......................................................................................................................................41 13.7 ir ............................................................................................................................................41 13.8 qir ..........................................................................................................................................42 13.9 ks ...........................................................................................................................................42 14 配置清单 ..................................................................................................................................43 14.1 ORB 的配置..........................................................................................................................43 14.2 POA 的配置..........................................................................................................................44 14.3 实现仓库的配置..................................................................................................................45 14.4 安全的配置..........................................................................................................................45 15 缺陷和反馈 ..............................................................................................................................47 16 附录 ..........................................................................................................................................48 4 1 前言前言前言前言 本文主要介绍 JacORB 的分布式应用开发。JacORB 是免费的 Java 对象请求代理系统,附带 全部源代码,包含大部分 CORBA 对象服务的实现,以及大量的代码实例。本文不是 CORBA 的一般性介绍,如果要看 CORBA 方面的介绍,请查阅附录的参考书目[BVD01]及 [HV99]。本文所描述的 JacORB 版本为 1.4Beta1,同时介绍一些安装和使用 JacORB 的技 巧。 5 2 安装安装安装安装 JacORB 本章的主要内容是获取和安装 JacORB,以及相关包的主要内容。 2.1 获取获取获取获取 JacORB JacORB 可以在 JacORB 的主页 http://www.jacorb.org 下载,也可以通过匿名方式访问 FTP 服 务器 ftp.inf.fu-berlin.de 目录 pub/jacorb 来下载。 下载的文件是压缩包,unix 为 tar 格式,windows 下为 zip 格式。要安装 JacORB,先解压 缩,会生成一个新的目录 JacORB1_4_beta1。然后将 JacORB1_4_beta1/lib/jacorb.jar加 (classpath) Jac入入入入入 入入入入入入入入入入 ORB ,,,,,,, JacORB1_4_beta1/class 加入类路径,并且将 JacORB1_4_beta1/bin 加到 Path,在 JacORB1_4_beta1/bin 下有一些实用程序。 2.2 安装安装安装安装 JacORB 2.2.1 Ant 和和和和 build.xml JacORB 可以在所有的 Java 虚拟机上运行。重新编译 JacORB(以及 JacORB 附带的例子)需要 安装 Ant,Ant 是基于 XML 的制作管理工具。你可以到 http://jakarta.apache.org/ant Ant build.xml下下下入下下下 入下下下 下下下下下下下下下入,入 JacORB (JacORB1_4_beta1) ant ant入入入 ,入新新新新新新新 入新入 新新新新入新新新 新新新 ant clean前,新前新新 前前前前前入入产生的中间文件。 最好使用 JDK1.2 以上的版本的虚拟机来运行 JacORB,因为图形工具如使命名管理器 (NameManger)、实现仓库管理器(ImRManger)、接口仓库浏览器(IRBrowser),以及 SSL 的支 持都需要 JDK1.2 以下版本的虚拟机。在使用 SSL 时,你还需要第三方的 SSL 协议实现, JacORB 目前支持以下的实现: 1.IAIKs下的的,的的新IAIK–JCE 2.5 SSL或或或下下入,前或 下或iSaSiLk3.0入。。。的的入新前。。。。。下。。入 2.Sun 的 JSSE 参考实现,包含在 JDK1.4 中;也可单独从 JDC 中下载。 2.2.2 配置配置配置配置 JacORB 有很多可以设为 Java 属性的配置项。在解释这些基本配置项之前,先让我们看看配 置方法。其他一些具体的配置项,如和实现仓库及交易服务相关的选项,在相关的章节讲 述。 总体说来,有三种方式可以配置 JacORB。 第一种方式是文件方式。JacORB 寻找和加载名为.jacorb_properties 或 jacorb.properties 文 件,系统将在下列位置搜索配置文件: 1.类路径中。 2.运行 JacORB 用户的用户主目录,通过运行 System.getProerty("user.home")获得。如果需要 知道用户主目录在哪,可以写一小段 Java 程序去测试一下。 3.当前目录中。 4.JDK 安装的 lib 目录。JDK 的主目录通过运行 System.getProperty("java.home")获得。 6 系统也按上述顺序搜索,一旦找到一个配置文件,系统将停止搜索,并加载该配置文件。 第二种方式是对象方式。对于和应用相关的配置项,可以在应用初始化时给 ORB.init 传递一 个 java.util.Property 对象。这种方式会覆盖使用文件方式设置的配置项。下面的代码片段演 示了如何向 ORB.init 传递一个 Property 对象(程序中 args 是命令行参数变量): java.util.Properties props = new java.util.Properties(); props.setProperty("jacorb.implname","StandardNS"); // use put() under Java 1.1 org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, props); 第三种方式是参数方式。可以通过设置 Java 虚拟机的系统属性来设置配置项,这些属性必 须在调用 ORB.init()之前设置,并且此方式会覆盖前两种方式设置的配置项。系统属性可用 System.setProperty,也可以用命令行参数方式 -D=,这是 Java 程 序的命令行参数,也可用于 jaco 脚本。需要注意的是这些参数必须放在类名参数之前,放 在类名参数之后的都将被 Java 虚拟机解释为该类的参数,并只被传递到该类的 main 方法 中。 如果你想通过命令行设置多个参数,你可以用一个特定的属性 custom.props,此属性值为配 置文件。在配置文件中你可以加上任意多的配置项。这里的配置项也会覆盖第一种和第二种 方式设置的配置项。例如:通常使用标准的 TCP/IP 连接,但可能有时候想使用 SSL。如果 只使用一个配置文件,那么要变更连接方式时就得修改配置文件。如果不想每次都修改配置 文件,也可以将不同的参数通过命令行参数传递,但这会导致很长的命令。但如果使用特定 的属性去指定文件,就可以把所有其他的配置项都放在该文件中,而只使用一个命令行参 数,如: $ jaco -Dcustom.props=ssl_props_MyServer 我们现在看一看最基本的配置项,下面是一个示例的配置文件: ## ## JacORB 配置项 ## ######################################## # # # 初始化的参考配置 # # # ######################################## # # IORs存储的URL (在orb.resolve_initial_service()中使用) # # # ORBInitRef在ORB启动时创建. In the # cases of the services themselves, this may lead to exceptions being # displayed (because the services aren’t up yet). These exceptions # are handled properly and cause no harm! #ORBInitRef.NameService=corbaloc::160.45.110.41:38693/StandardNS/NameSer ver POA/_root #ORBInitRef.NameService=file:/c:/NS_Ref ORBInitRef.NameService=http://www.x.y.z/~user/NS_Ref #ORBInitRef.TradingService=http://www.x.y.z/~user/TraderRef # JacORB-specific URLs jacorb.ImplementationRepositoryURL=http://www.x.y.z/~user/ImR_Ref jacorb.ProxyServerURL=http://www.x.y.z/~user/Appligator_Ref ################################## # # 7 # 调试模式 # # # ################################## # use (java) jacorb.util.CAD to generate an appropriate # verbosity level # 0 = off # 1 = important messages and exceptions # 2 = informational messages and exceptions # >= 3 = debug-level output (may confuse the unaware user :-) jacorb.verbosity=1 # where does output go? Terminal is default #jacorb.logfile=LOGFILEPATH ################################################## # # # WARNING: The following properties should # # only be edited by the expert user. They # # can be left untouched for most cases! # # # ################################################## ################################ # # # 基本ORB配置 # # # ################################ # number of retries if connection cannot directly be established jacorb.retries=5 # how many msecs. do we wait between retries jacorb.retry_interval=500 # size of network buffers for outgoing messages jacorb.outbuf_size=2048 # client-side timeout, set no non-zero to stop blocking # after so many msecs. #jacorb.connection.client_timeout=0 # max time a server keeps a connection open if nothing happens #jacorb.connection.server_timeout=10000 #jacorb.reference_caching=off ... ######################### # # # POA配置 # # # ######################### # displays a GUI monitoring tool for servers jacorb.poa.monitoring=off # thread pool configuration for request processing jacorb.poa.thread_pool_max=20 jacorb.poa.thread_pool_min=5 # if set, request processing threads in thePOA # will run at this priority. If not set or invalid, # MAX_PRIORITY will be used. #jacorb.poa.thread_priority= # size of the request queue, clients will receive Corba.TRANSIENT # exceptions if load exceeds this limit jacorb.poa.queue_max=100 ... 配置项包括网络缓冲区的大小、JacORB 在不能建立连接时的重试次数、在重试前等待的时 间间隔。ORBInitRef.NameService 的值是 JacORB 命名服务的 URL。这个 URL 被 ORB 用来 定位存储服务对象引用的文件(请参见第 4 章)。 verbosity 配置项指定 JacORB 在运行时可以忽略多少诊断输出。除非将 logfile 配置 8 项设定为一个文件,否则系统将向终端输出日志。将 verbosity 置为 0 意味着不输出任何诊断 信息,2 为详细诊断信息输出。1 则忽略某些信息,例如忽略连接打开、接受和关闭的信 息。如果想可选的输出一些诊断信息,可以使用 jacorb.util.CAD 工具生成一个自定义的输出 级别。 配置项 jacorb.poa.monitoring 指明 POA 是否打开一个图形界面显示自身的动态信息,例如有 多长的请求队列,有多大的线程池。同时,这个工具也可以用来修改 POA 的状态,从活动 到保持,详细说明可以参见第 5 章。 现在就可以在 demo 目录下任一子目录来测试安装。在此目录下有很多 JacORB 的例子。 9 3 编程起步编程起步编程起步编程起步 在开始讲述例子之前,我们先看一下在 JacORB 中开发 CORBA 应用的基本步骤。我们也按 照这个基本步骤来讲述例子。例子请参见 demo/grid 目录,在此目录有一个 build.xml,用以 使用 ant 来制作,这样不用每回都手工运行每一开发步骤,当然还是应该搞清楚开发的原 理。 本文只是 JacORB 编程的简短介绍,不会涉及 CORBA IDL 的所有细节,建议看看 demo 下 的其他例子,这些例子是按照 CORBA IDL 的方式进行组织的。 3.1 JacORB 开发步骤开发步骤开发步骤开发步骤 JacORB 的应用开发一般分为以下五步: 1.写 IDL 接口定义 2.编译 IDL 接口定义生成 Java 类 3.实现步骤 2 中生成的接口 4.写服务器启动类,并注册到 ORB 5.写客户端去获取服务对象引用 3.2 IDL 接口定义接口定义接口定义接口定义 本例实现了一个简单的服务,其接口在 server.idl 中定义。本例所有的源代码都可以在 jacORB1_4_beta1/demo/grid 目录下找到。 下面是 server.idl 文件的内容: // server.idl // 二维网格的接口定义: module demo { module grid { interface MyServer { typedef fixed <5,2> fixedT; readonly attribute short height; // 网络的高度 readonly attribute short width; // 网络的宽度 // 设置n*m的网络 void set(in short n, in short m, in fixedT value); // 返回n*m的网络元素 fixedT get(in short n, in short m); exception MyException { string why; }; short opWithException() raises( MyException ); }; }; }; 10 3.3 生成生成生成生成 Java 类类类类 使用如下命令编译此接口文件: $idl -d ../.. server.idl 此命令将生成多个 Java 源文件,Java 源文件的生成依照 OMG 标准的 IDL-Java 语言映射定 义。如果你对语言映射定义感兴趣,例如 IDL 的语言结构如何映射为 Java 的语言结构,可 以到 www.omg.org 上查找相关文档。JacORB 的 IDL 编译使用 CORBA2.3 定义的语言映射, 详细说明可参考附录的参考书目[BVD01]。如何使用 idl 接口定义,可参考 demo 目录下的例 子。 IDL 编译器产生 Java 接口 MyServer、MyServerOptions,及桩和骨架文件_MyServerStub、 MyServerPOA、MyServerPOATie。我们将在后面详细这几个类。 注意 IDL 编译器将会产生一个和 IDL 接口文件中定义模块相对应的目录结构。如果我们不 指定-d ../..,将在当前目录下创建 demo/grid 子目录。 如何存放生成的 Java 源文件各有所好,有人喜欢所所有的文件都放在一个地方(可以使用-d 选项),有人喜欢一个目录存放生成的的源文件,另外一个目录存放 Java 编译产生的 class 文 件。 3.4 实现接口实现接口实现接口实现接口 现在我们来实现接口定义中描述的功能。这个 Java 类命名为 gridImpl,除了要实现接口定义 中描述的所有功能外,gridImpl 还应该是在前面生成的类 MyServerPOA 的子类。 MyServerPOA 中包含接受远程调用和将结果返回给客户的端的相关代码。 你也许注意到当 gridImpl 要继承另外一个类时,这种方式就有局限性。因为 Java 只允许继 承一个父类,在后面将讲到用桥接方式解决这个问题。 这是 gridImpl 的源代码,在代码中使用 java.math.BigDecimal 来保存接口定义中的 fixedT 类 型。 package demo.grid; /** * A very simple implementation of a 2-D grid */ import demo.grid.MyServerPackage.MyException; public class gridImpl extends MyServerPOA { protected short height = 31; protected short width = 14; protected java.math.BigDecimal[][] mygrid; public gridImpl() { mygrid = new java.math.BigDecimal[height][width]; for( short h = 0; h < height; h++ ) { for( short w = 0; w < width; w++ ) { mygrid[h][w] = new java.math.BigDecimal("0.21"); } } } public java.math.BigDecimal get(short n, short m) { if( ( n <= height ) && ( m <= width ) ) return mygrid[n][m]; 11 else return new java.math.BigDecimal("0.01"); } public short height() { return height; } public void set(short n, short m, java.math.BigDecimal value) { if( ( n <= height ) && ( m <= width ) ) mygrid[n][m] = value; } public short width() { return width; } public short opWithException() throws demo.grid.MyServerPackage.MyException { throw new demo.grid.MyServerPackage.MyException("This is only a test exception, } } 3.5 编写服务器编写服务器编写服务器编写服务器 这一步要写一个类来调用 gridImpl 类,并将其注册到 POA,这样远程对象才能通过 MyServer 接口来访问它。以下是这个类的源代码: package demo.grid; import java.io.*; import org.omg.CosNaming.*; public class Server { ////// public static void main( String[] args ) { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); try { org.omg.PortableServer.POA poa = org.omg.PortableServer.POAHelper.narrow( orb.resolve_initial_references("RootPOA")); poa.the_POAManager().activate(); org.omg.CORBA.Object o = poa.servant_to_reference(new gridImpl()); if( args.length == 1 ) { // write the object reference to args[0] PrintWriter ps = new PrintWriter( new FileOutputStream( new File( args[0] ))); ps.println( orb.object_to_string( o ) ); ps.close(); } else { // register with the naming service NamingContextExt nc = NamingContextExtHelper.narrow( orb.resolve_initial_references("NameService")); nc.bind( nc.to_name("grid.example"), o); 12 } } catch ( Exception e ) { e.printStackTrace(); } orb.run(); } } 在初始化ORB之后,要获取一个POA的引用。ORB可以通过"RootPOA"来获取一个初始引用,此引用 只是一个CORBA.Object,需要使用POAHelper来实例化为POA的引用。下一步是激活该对象,因为 引用刚创建时是“保持”状态,在这种状态下,不能处理任何请求。通过调用POA的POAManager对象 的activate()方法将POA激活。现在就可以通过POA将一个Java对象转化成一个CORBA对象。 为了使新创建的CORBA对象能被客户端访问,我们要提供该对象的引用。这一过程通过目录服务-- 命名服务器--来完成。命名服务 器的引用通过调用 orb.resolve_initial_references("NameService"),然后用 org.omg.CosNaming.NamingContextExtHelper 的narrow()方法实例化为正确的命名服务器对象。最后,调用命名服务器的bind()方法将CORBA对 象引用进行发布。对象的名称作为bind()的参数传入,当然,不能只传递一个字符串,而是应传入代 表名称的 CosNaming.NameComponents对对入新前对入,对对对。对对下对对下新的的的,新前的的的, 的名名名下的名对对入 3.6 编写客户端编写客户端编写客户端编写客户端 下最,最对对前最对最。。。下入最最。的的最最下最 package demo.grid; import org.omg.CosNaming.*; public class Client { public static void main(String args[]) { try { MyServer grid; org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null); if(args.length==1 ) { // args[0] is an IOR-string grid = MyServerHelper.narrow(orb.string_to_object(args[0])); } else { NamingContextExt nc = NamingContextExtHelper.narrow( orb.resolve_initial_references("NameService")); grid = MyServerHelper.narrow( nc.resolve(nc.to_name("grid.example"))); } short x = grid.height(); System.out.println("Height = " + x); short y = grid.width(); System.out.println("Width = " + y); x -= 1; y -= 1; 13 System.out.println("Old value at (" + x + "," + y +"): " + grid.get( x,y)); System.out.println("Setting (" + x + "," + y +") to 470.11"); grid.set( x, y, new java.math.BigDecimal("470.11")); System.out.println("New value at (" + x + "," + y +"): " + grid.get( x,y)); try { grid.opWithException(); } catch (jacorb.demo.grid.MyServerPackage.MyException ex) { System.out.println("MyException, reason: " + ex.why); } } catch (Exception e) { e.printStackTrace(); } } } 在初始化ORB之后,客户端通过命名服务器获取一个"grid"服务的引用。如上所述,通过调用 orb.resolve initial references("NameService")获取命名服务,使用resolve()方法在命 名服务器上查找"grid"的引用。返回的结果是org.omg.CORBA.Object对象,需要实例化为 MyServer。 在将所有的Java类都成功编译以后,现在可以在不同的Java虚拟机中启动服务器和客户端。当然,应 该是命名服务最先启动,如果命名服务还没有启动,使用以下命令来启动: $ns /home/me/public_html/NS_Ref /home/me/public_html/NS_Ref是一个本地的可写文件,服务器和客户端都可以通过URL的方 式访问。这样,可以不使用端口号,而服务器和客户端都可以获取命名服务的引用,从而实现互相 访问。 启动服务器: $jaco demo.grid.Server 接着,运行客户端: $jaco demo.grid.Client 运行客户端产生以下输出: Height = 31 Width = 14 Old value at (30,13): 0.21 Setting (30,13) to 470.11 New value at (30,13): 470.11 MyException, reason: This is only a test exception, no harm done :-) done. 3.7 桥接方式桥接方式桥接方式桥接方式 如果在实现接口已经继承了另外一个类,而不能继承MyServerPOA时,可以使用桥接方式。简言 之,这种方式将继承改为指派,不是继承MyServerPOA,则是实现MyServerOperations接接入 package demo.grid; import demo.grid.MyServerPackage.MyException; public class gridOperationsImpl implements MyServerOperations 14 { ... } 的的服服。前下的服的的最 package demo.grid; import java.io.*; import org.omg.CosNaming.*; public class TieServer { public static void main( String[] args ) { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); try { org.omg.PortableServer.POA poa = org.omg.PortableServer.POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // use the operations implementation and wrap it in // a tie object org.omg.CORBA.Object o = poa.servant_to_reference( new MyServerPOATie( new gridOperationsImpl()) ); poa.the_POAManager().activate(); if( args.length == 1 ) { // write the object reference to args[0] PrintWriter ps = new PrintWriter( new FileOutputStream(new File( args[0] ))); ps.println( orb.object_to_string( o ) ); ps.close(); } else { NamingContextExt nc = NamingContextExtHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent [] name = new NameComponent[1]; name[0] = new NameComponent("grid", "whatever"); nc.bind( name, o ); } } catch ( Exception e ) { e.printStackTrace(); } orb.run(); } } 15 4 JacORB 命名服务命名服务命名服务命名服务 新的的的。。命命下的服命命对对,。入最命,。命,命命服命命命的命入入入新前。的的的命命 找找找找的的下对对,。。。找新前,。找找找找的的下对对新找入的名命的的下找命下找找对。 。。前户下户户下入 JacORB OMG (INS)的的对 下实实新的的的 ,找找,的实找命下对对实。,实实的实命找对对实。下 JacORB功功入,找找功功最。。。新功功功功的新的实命实功功新功功新名功入 新的的的功功功功 组组最对下下的的最最,组对下下对组新前。。的的最最下入命接接入 JDK1.2 JDK新。。 前前下下在,新,在在 下功在 bug命新的的的和找下入下实在对,和和和新 ,下和 JacORB,将将 ,功将将下实入下对,下入下。将下入,下命。NamingContextExt来代替 NamingContext接口,否则,总会碰到空指针或其他异常。在JDK1.1 中没有这些问题。 4.1 运行命名服务运行命名服务运行命名服务运行命名服务 JacORB命名服务是一个程序,需要在访问前启动。使用如下命令启动: $ns [] 也可以通过java程序直接启动: $jaco jacorb.naming.NameServer [] 在上例中 $ns /home/me/public_html/NS_Ref 命名服务将位置信息和日志信息写入/home/me/public_html/NS_Ref文件中。客户端使用这个 文件来定位命名服务。但是,在默认情况下,客户端并不是通过本地或共享文件的方式来读取该文 件,而是使用URL通过http协议来访问。这也表明命名服务日志文件可能通过HTTP方式进行访问, 如果知道位于域中哪一个Web服务器中。 这种实现方式的优点在于客户端不必知道命名服务的端口号,而是通过URL的方式来访问。如果想 限制命名服务在域中的可见性,或者无法访问一个Web服务器,那么可以使用文件URL的方式来代 替HTTP的URL方式,例如,可以使用如下方式 file:/home/brose/public_html/NS_Ref 来替代 http://www.inf.fu-berlin.de/~brose/NS_Ref 使用URL的方式也方便没有网络连接的机器,请注意HTTP协议并不总能被使用,当客户端已经定位 命名服务以后,后续的请求将使用标准的CORBA方法调用,也就是使用IIOP协议(基于TCP/IP)。 命名服务将自身的内部状态,例如在命名空间中绑定的名称,存储在当前目录的文件中。目录也可 以用参数jacorb.naming.db_dir来指定。当命名服务正常终止时,内部状态都将被保存,但使 用Kill或Control-C时会造成数据丢失。如果状态文件存在且不为空,命名服务就能从该文件中恢复状 态。 第二个参数是以毫秒计算的超时值。如果这个参数被设置,则命名服务在到运行指定时间后,将保 存状态并正常关闭。这种方式在命名服务注册到实现仓库时很有用,这样,命名服务可以按需启 动。 配置根命名空间 配置一个命名空间(例如命名服务)作为ORB根命名空间,只需要将启动文件指定到配置文 件.jacorbproperties即可。也可以将启动文件设为配置项ORBInitRef.NameService的值。 在根命名空间配置好以后,对象 NamingContextExt下下下最。下,。。orb.resolve_initial_references("NameService") ,,,,,,新的的的,,,,或,的的,或,,入 16 4.2 访问命名服务访问命名服务访问命名服务访问命名服务 JacORB新入 CORBA实实通通下 命通的服。。新的的的最 //获取命名服务的引用 ORB orb = ORB.init(args, null); org.omg.CORBA.Object o = orb.resolve_initial_references("NameService") NamingContextExt nc = NamingContextExtHelper.narrow( o ); //查找对象 server s = serverHelper.narrow( nc.resolve(nc.to_name("server.service")) ); 在查找对象之前,需要获取命名服务的引用。获取引用的标准方式是调用 orb.resolve_initial_references("NameService"),。。下,的服最。,对对下新的的 的,对对的实下对下NameComponents数组功新数数,下数功数数数数的名入实实下,的服,新前 "server" "service"数构下数对下数组,构命的的下的下 ,入构下 ,构,。构命对下新的构功入组构, ,新前最。接接NamingContextExt的方法to_name()将字符串"server.service"转化结构名称。 然后,可以在名称命名空间中调用resolve()方法来查找对象,并传递一个结构名称作为参数。 4.3 构造层次命名空间构造层次命名空间构造层次命名空间构造层次命名空间 就象文件系统的目录结构一样,命名空间也可以包含其他的命名空间,从而构成层次结构,而不是 平面结构。对象的结构名称的各部分就构成了名称的路径,在最内层的命名空间中绑定对象的名 称。这可以使用命名管理器实现,或者通过编码实现。 在已有的命名空间中创建新的子命名空间可以通过new_context()或bind_new context()方法。下面 的代码片段演示了如何创建一个子命名空间,并返回它的引用: // get a reference to the naming service ORB orb = ORB.init(); org.omg.CORBA.Object o = orb.resolve_initial_references("NameService"); NamingContextExt rootContext = NamingContextExtHelper.narrow( o ); // look up an object NameComponent[] name = new NameComponent[1]; name[0] = new NameComponent("sub","context"); NamingContextExt subContext = NamingContextExtHelper.narrow( rootContext.bind_new_context( name )); 请注意在JacORB中总是在内部使用NamingContextExt对象,即使代码中写的是NamingContext 对象,原因在前面已经描述过。 4.4 命名管理器命名管理器命名管理器命名管理器 如果使用JDK1.2 以上的Java虚拟机,或带有JFC相关类。图形界面的命名管理器就可以通过以下命令 启动: $nmg 命名管理器启动以后查找根命名空间并显示其内容,请看屏幕截图: 17 命名管理器有绑定名称,创建子命名空间的菜单。如图,右击RootContext,在弹出的菜单中选择new context,输入名称,可创建子命名空间。 18 5 服务端:服务端:服务端:服务端:POA 及线程及线程及线程及线程 本章介绍JacORB提供控制服务启动和运行的应用及接口,包括激活服务、可移植对象适配器 (POA)、线程。 本章只给出一个POA的简单介绍,并不涉及如何使用POA不同的设置和不同的策略,详细信息可以 参考附录的参考书目[BVD01],也可参考另一书目[HV99, Vin98] C++入入最新 入。。新。。命。http://www.cs.wustl.edu/~schmidt/report- doc.html CORBA前下和找上上,下上下。。下 上上入 5.1 POA POA提供复杂的接口来管理对象引用及伺服程序。使用POA接口写的代码现在可以在兼容CORBA2.2 或以上版本的各个ORB中移植。 POA定义了以下几个方面的标准接口: !映射对象引用到实现对象的伺服程序 !允许透明地激活对象 !将策略信息绑定到对象 !可以在几个服务进程中持续化CORBA对象 在POA规范中,已经废弃了伪IDL的使用,而直接使用标准IDL,使用标准的语言映射定义来将IDL 映射为编程语言,但这有本地限制。因为这意味着对象引用不能传递到服务器地址空间以外,POA 接口本身也是有本地限制的。 POA是CORBA负责创建CORBA对象及对象引用的部分,并且,也有助于骨架(skeleton)将请求调度 到真正的对象。为了和实现仓库一致,也可以激活对象,例如,启动提供CORBA对象程序的进程。 5.2 线程线程线程线程 JacORB提供服务器端线程模式。POA负责调度中央线程池从中获得一个线程来处理请求。线程池的 大小由参数jacorb.poa.thread_pool_max和jacorb.poa.thread_pool_min决定。 当一个请求到达时,如果线程池中的所有线程都忙,并且线程总数小于 jacorb.poa.thread_pool_max时,会启动一个新线程来处理请求。否则,请求将会阻塞直至有 可用的线程。当线程处理完一个请求之后,必须决定是返回线程池还是被销毁。当线程池已经超过 最小值时,处理中的线程不会返回线程池,从而保证线程池总在最大值和最小值之间。 将最小值设置为大于 1,意味着在线程池中总有一些线程处于激活状态等待处理请求。这对于请求以 脉冲方式到达的情况最为有效。限制线程池的最大值可以防止服务器占用过多的资源。 请求处理线程通常以较高的线程优先级运行。线程优先级通过参数 jacorb.poa.thread_priority来设置,参数值为Thread.MIN_PRIORITY Thread.MAX_ 、 PRIORITY Thread.NORMAL_ 、 PRIORITY JacORB Thread.MAX_PRIORITY新对,入入之之之之, ,之之之下 入 19 6 实现仓库实现仓库实现仓库实现仓库 实现仓库(ImR)并不象其名所表述的,是一个保存实现的数据库。相反,它只保存如何将请求调度到 真正的CORBA对象,如何实例化一个实现的信息。"实例化一个实现"是指启动一个包含所需CORBA 对象的服务程序。在本章我们只是简单介绍如何使用实现仓库,详细信息请参考[HV99]。 6.1 概述概述概述概述 POA对一的,的的,或入一和一,入最。。一一对对实。下一一入对下一一对对实。下 实实一一一 POA新命命命命下入下在命找对对下一新命命命命命命下 命命一入新的的,或入。。一一对对实。 ,的的,或找新前,。找找,一,入前在,对对下,和新,入入,和新,找命命对下入 下对为入下下新下,的的,或为为为为为下一,命一一对对下找为入下对为新前实实入下一一对对 实。,。之的的的的,或下的命一一,构,下的的的的最最的命一一前为入入引。,一,引引入为 的的,或,构,下的实下的的最最,引下的的最最新功新一,入为在和,和新入入入下数下一,入 为的的,或,的的,或引引新达功达入命找的的下一一,达达下下的的对对和,和新,入入,和新 ,的的,或下,,下一一前,,对下和找下的的对对,新的的对对,前前最,的的,或,,。。。 LOCATION_FORWARD对下 下一将,新。一将入,的的入的的对对实。,下数,。。。功户户的。 。入的的对对实。前。。一,入 6.2 使用使用使用使用 JacORB 的实现仓库的实现仓库的实现仓库的实现仓库 JacORB的的,或功功功功组组最,或功最,新实入新和新对下实的的,,功最,新为对实新,,, 下的的下的命前下,下对下入在在,,新,对下。。下下功理一新命命理理对对下功最入 ()引引,为为引,,入首,或功最 新的的,或 最 $imr [-n] [-p ] [-i ][-f ][-b ] [-a] 的的,或。。实之实ORBInitRef.ImplementationRepository前命命入下下来理上来为为之 WEB IOR之入对下新。下 的的服前,和和的的,或下 功,置置入下对置,,,功最新新,下的命前 ,,,。。入下新新最 $imr_ssd ,,,功最,,在,命当命的的,或实当入 。。前下新新,新前,,,下的的在以入的的,或,新功。。的的,或下以最的命下新前。。。新 新入 $imr_mg add "AServerName" -c "jaco MyServer" imr_mg add新新下命实的的,或下实。新新入新前命新新入,。数 构户,的的在以入的的,或,命接 着下。数下的的的,入入的的下新的命,下下命,命新,。。数-h hostname前构命新下的命入下最,的的,或新,为为入最,,的的,功。数-c jaco 前构命, MyServer户户对入最,,下的的入- c。数下参服命,,的的下新新对数,下下新新为为的的 Windows s下新的命功新新入入新 下新前。。 tart jaco MyServer unix,的的,,入将将下将将实入,新 下将新前。。xterm -e jaco MyServer 来实现同一目的。 启动命令作为一个字符串将完整直接地传递到Runtime.exec()方法中,不会被解释或修改。因 为Runtime.exec()是和平台相关的,所以启动参数也和平台相关。大多数unix系统中可以使用*或 ~来防止shell解释,windows系统不将字符串传递给命令行解释器,因此,即使在dos提示符下输入 jaco MyServer能执行,也不能保证将此字符串作为imr_mg能成功。最好将启动命令封装成直接调用 命令行解释器,在NT下,使用如下命令:cmd /c "jaco MyServer" imr_mg入一,。,新。。 之之,,新新在,,,新新入下。实。功新名。入 入入,入最的的功的的,或如,,,,新前之之实之实jacorb.imr.allow_auto_register或 20 使用实现仓库命令的-a参数。如果此配置项被设置,在POA激活时,实现仓库交自动为服务创建一个 新配置,如果服务以前没有注册到实现仓库,那么,不能通过实现仓库管理器来注册该服务。 客户端需要一个服务对象引用来提交请求,直接现在,我们还没有提到如何将持久对象引用激活的 问题。引用创建和通常一样,当一个引用被创建成可持久化,POA必须使用持久生命周期策略来创 建它,如以下代码所示: /* 初始化ORB和根POA */ orb = org.omg.CORBA.ORB.init(args, props); org.omg.PortableServer.POA rootPOA =org.omg.PortableServer.POAHelper.narrow( orb.resolve_initial_references("RootPOA")); /* 生成策略 */ org.omg.CORBA.Policy [] policies = new org.omg.CORBA.Policy[2]; policies[0] = rootPOA.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID); policies[1] = rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT); /* 创建POA */ POA myPOA = rootPOA.create_POA("XYZPOA",rootPOA.the_POAManager(), policies); /* 激活POA */ poa.the_POAManager().activate(); 注意,使用持久对象引用的POA其ID应设置为USER_ID,因为这个值会在保存对象状态时保存到状 态库中。如果POA使用持久生命周期策略创建,并且ORB的"use_imr"配置项已经设置,ORB会通知 实现仓库,因此,实现仓库知道不用创建一个新的对象来处理请求。只需将ORB的配置项设置为: jacorb.use imr=on ORB新新入 。。组对下实之实jacorb.implname实下实为下。数入入入的的,,在以入的 的,或,实之实下之现找命在以在。。下的的的现实入 新最最入新前实实新新新。数- Djacorb.implname=MyName之之下下之,,新前。。前下设。前之之最 /* create and set properties */ java.util.Properties props = new java.util.Properties(); props.setProperty("jacorb.use_imr","on"); props.setProperty("jacorb.implname","MyName"); /* init ORB */ orb = org.omg.CORBA.ORB.init(args, props); ,新,,在当当对对当当或新找当在一和对对当当,下当来当当新,在在入新,,在,对对当当新 最后后名后后后组 POA,引下新下下在,对对后功接,一,入,或新,对下下下一一一新命命下在 以新最,后功为为的的,册。在命,功,的的实。数数,。。。,引下的的和,册将新。入新前册 决。。将下对下,新决下的决下决加实之实jacorb.imr.object_activation_sleep下之,下 数,的的,或新,或命下在功前后组,,,样构新前样样的的找样入 POA新的的找当在,,新在的的下当当,下最下 一和在,引下的的,或在下的的,,找当,入入。 在下入下一,入前,的的,或找当,,对下入下的的功最前。。入。在,的的下的的命现找在在的 POA POA的一和当当命置置当当新功下务置。将入对下册决的决下。。 务。服, 之之下新一和一一 POA或,当,在,。或一一当当,下数一,当,或或或 当当入 POA o一,。新。新的的找当在入,。命一和的的下当当,新请请在,对命,, 理当,新前实实最。 rb.shutdown(...) IOR,,将的的,或在下的的,,当,,样构,。。。,,之之下 入新的的,,在新 imr_mg setdown AserverName前。。新新 前实为的的,或找的的,,入止入 6.3 服务迁移服务迁移服务迁移服务迁移 POA的的,或找找对组对实下。下功功最的的实实入之入前下实实最,。。一一 前的的的的在,新 对一在功前最,的命找一功一,前或或功一。。下下下一,入下在,,,的的实实入对实或一一下 21 的命前下。下,,下当入。。的的,或,。。实。,的的的的下的命一一,引。,新前户户的后组 的的实实入 对入,入新对实一下的命前,,的的最 $imr_mg add AServerName -h a_slow_machine -c "jaco MyServer" ,对置下一一的的,下在命的的,或,或或下下下一,第或的的务前,务入 $imr_mg hold AServerName POA POA的新,的的,功接,,在以 ,入入,功新的的现止在。。 理当,入新前。。前下新新最 $imr_mg setdown AServerName POA POA,将, ,,功务前,当当,引下的的,或在下对第。或当,当当入 入入如如的的,如,,,,入新,实为的的,或入下的命的命,,新功命下入下,,新新最 $imr_mg edit AServerName -h the_fastest_available_machine -c "jaco MyServer" 入入的的功如,,,,入找,为如下,,,命,当新,对一,入为在,的的,或,,入,,,入, 新前新入的命前如下,,入 下最对置下,务的的,最下下或或下一,新前,。。最 $imr_mg release AServerName 的新,的的找现新新入下的命前,构,。实为。。。入 6.4 安全考虑安全考虑安全考虑安全考虑 IOR服。的的,或新功当对为采数组新采采采入。采前下当采最的的,或现新新对实的命前,命下 采 WEB之新对下新前, 的的服。。下新新下,新组构下当实的命前现新着当下的的,,功最入对下置 击命新前新对实现新的的,,功最下的命前新新前下命实最 ,实之实ORBInitRef.ImplementationRepository IOR之下的的,或下新的,下 上来 入 1.创建一个入侵服务,在想入侵的主机(已有ssd在运行)执行一个非法的启动命令。这是最关键 的一点,因为服务启动进程只是将启动命令作为参数传递给Runtime.exec(),而没有方法去 检查命令是否合法,例如是否是启动一个服务。 2.使用imr_mg启动该入侵服务,指定的命令将在被入侵的主机上执行。 虽然有风险,但并不是不鼓励使用实现仓库,这个风险可以使用以下方法显著降低: 1.控制IOR文件的分发。但不要使用隐藏文件的方式,这不是一个好方法。最好使用文件系统 的组策略或访问控制策略(ACL)。 2.使用防火墙来过虑请求。但要注意,当攻击来自内部时,防火墙很难防范。也要注意,写 一个穿过防火墙的木马程序并不是很困难的事。 3.使用SSL连接来访问实现仓库。这可以阻止没有合法客户端证书的访问,详见第 9 章。 22 7 Any Value 的动态管理的动态管理的动态管理的动态管理 本章的目的是描述DynAny规范,这个规范是关于Any Values的动态管理。本章仅仅描述DynAny 规范的主要特性。 如果想得到本章内容全部相关的参考,请取得OMG的关于CORBA规范,自行参考。 7.1 概述概述概述概述 DynAny 对象被用来动态构造和传输访问任意类型的值。一个 DynAny 可以描述一个基本类型,例如 boolean 或者 long,或者一个构造类型,例如 enum 或 struct。 7.2 接口接口接口接口 下面的UML框图说明了org.omg包中的接口之间的关系。 DynAny 接口是描述基本类型的基类接口。针对每一种结构类型,有一个对应的从 DynAny 接口继承 的接口和定义的一些专用于这些结构类型的操作。下面的表格列出了动态任意(DynamicAny)模型 和他们所描述的值。 7.3 用法限制用法限制用法限制用法限制 23 从 DynamicAny 模块中的接口实现的对象,被有意的本地化来处理结构类型。结果是,这些对象的 引用不能导出到别的程序中或使用 ORB::object 到 string 的下塑造型;一个试图这样做的操作将抛出 MARSHAL 系统异常。 7.4 创建一个创建一个创建一个创建一个 DynAny 对象对象对象对象 DynAnyFactory 接口被用来创建 DynAny 对象。有两个操作用来创建 DynAny 对象;在下表列出。 下面的例子演示了怎样获得一个DynAnyFacory对象的引用,然后使用他的每个构建操作来构建一个 DnyAny对象。 下面的代码导入DynamicAny包中的类。 import org.omg.DynamicAny.*; 下面的代码片断获得一个 DynAnyFacory 对象的应用。 DynAnyFactory factory = null; DynAny DynAny = null; DynAny DynAny2 = null; org.omg.CORBA.Any any = null; org.omg.CORBA.TypeCode tc = null; org.omg.CORBA.Object obj = null; //获得DynAnyFactory的对象引用 obj = orb.resolve_initial_references ("DynAnyFactory"); //转换应用到正确类型 factory = DynAnyFactoryHelper.narrow (obj); 下面的代码片断使用每种创建方法创建DynAny对象。 //从Any创建一个DnyAny对象 any = orb.create_any (); any.insert_long (1); DynAny = factory.create_dyn_any (any); //从TypeCode创建一个DynAny对象 tc = orb.get_primitive_tc (org.omg.CORBA.TCKind.tk_long); DynAny2 = factory.create_dyn_any_from_type_code (tc); 如果Any Value或者TypeCode描述一个结构类型,那么DynAny可以转换到适当的类型,例示如下。 下面的IDL定义一个结构类型 // example struct type struct StructType { long field1; string field2; }; 下面的代码例示了一个代表StructType类型值的DynStruct对象的创建 StructType type = null; DynStruct dynStruct = null; //创建一个包含StructType对象类型的Any type = new StructType (999, "Hello"); any = orb.create_any (); StructTypeHelper.insert (any, type); 24 //从一个Any和将他造型到一个DynStruct构建一个DynAny dynStruct = (DynStruct) factory.create_dyn_any (any); 7.5 访问访问访问访问 DynAny 对象的值对象的值对象的值对象的值 DynAny接口定义了一套用于访问代表基本类型的DynAny对象的操作。这个用来从DynAny对 象获得基本类型的值的操作用这样的方式get_。用来插入基本类型值的到DynAny对象 使用这样的形式insert_。如果类型操作使用得get/insert一个值到一个DynAny对象类型匹配错 误,将抛出TypeMismatch异常。` 用来访问代表构造类型的的 DynAny 的操作是专门针对构造类型设计的。例如,DynStruct 接口定义 一个访问成员的操作,他返回一个代表这个 DynStruct 对象的结构或者异常的成员的名称/值对序 列。 7.6 传送传送传送传送 DynAny 对象的值对象的值对象的值对象的值 DynAny对象可以被看作是一个有序的DynAny的集合。例如,在一个DynStruct对象中,他代表的是 许多结构和异常的有序集合。因为DynAny对象表示的是基本类型和没有其他成分的构造类型, DynAny的成分集合是空的。 所有的DynAny对象拥有当前位置。例如在一个代表构造类型的DynAny中,当前的位置就是这个 DynAny中,这个将要被调用的成分的位置(在下表说明)。DynAny对象中的DynAny成分的索引从 0到n-1;n是成分的数量。例如DynAny表示基本类型或没有成分的构造类型,当前的位置缺省值就 是-1。 用来访问DynAny对象的DynAny成分的操作对所有的DynAyn的子类型通用,所以这些操作定义在基 类接口中。下表列出了用来访问DynAny对象的可用操作。 下面的代码例示了一种访问一个DynStruct对象的DynAny成分的方法。当DynStruct被访问,每个成分 的值被取到和打印。这里忽略了异常。 DynAny curComp = null; //打印第一个成分的值 curComp = dynStruct.current_component (); System.out.println ("field1 = " + curComp.get_long ()); //前进到下一个 dynStruct.next (); //打印第二个成分的值 curComp = dynStruct.current_component (); System.out.println ("field2 = " + curComp.get_string ()); 下面的代码演示了完成同样任务的另一种方法。 // go back to the first component dynStruct.rewind (); // same as calling seek (0) 25 // print the value of the first component //打印第一个成分的值 System.out.println ("field1 = " + dynStruct.get_long ()); //前进到下一个 dynStruct.seek (1); //打印第二个成分的值 System.out.println ("field2 = " + dynStruct.get_string ()); 在第二段演示代码中,如果成分 DynAny 代表一个基本类型,可用通过调用他的父类的 DynAny 的访 问操作直接访问,比调用当前的成分的访问操作方式要好。 7.7 构造类型构造类型构造类型构造类型 这部分描述JacORB中支持的DynamicAny模型中的接口。这些接口都是从DynAny接口继承而来。 7.7.1 DynEnum 一个DynEnum对象代表一个枚举值。枚举的整型值能够通过作为ulong类型的get和set操作被访问到。 枚举的字符串值能够使用字符串的get和set操作访问。 一个DynEnum对象没有其他的成分。 7.7.2 DynStruct 一个DynStruct对象代表一个结构值或者一个异常值。当前的成员名称和当前的成员类操作返回名称 和DynStruct的当前位置的成员的TypeCode的TCKind值。DynStruct的成员可以通过get和set方法访 问。 一个DynStruct对象的成分DynAny是结构或异常的成员。一个DynStruct代表一个没有成分的空异常。 7.7.3 DynUnion 一个DynUnion对象代表一个联合体(union)值。辨别器(discriminator)的值可以通过使用get和set方 法访问。 如果辨别器被设置为一个联合体(union)的成员名称,那么这个成员就变成活动的。否则,就不是 活动成员。 如果存在活动成员,成员操作返回的值作为一个 DynAny 对象,并且这个成员和成员性质的操作返 回他的名字和它的 TypeCode 的 TCKind 值。如果这个联合体没有活动成员,这些操作将抛出 InvalidValue 异常。一个 DynUnion 对象可以拥有一个或两个成分。第一成分总是辨别器的值。如果 活动成员存在,第二个成分就是活动成员的值。 7.7.4 DynSequence 一个DynSequence对象代表一个序列。序列的长度可以通过使用长度的get和set操作得到。序列的 元素可以通过元素set和get操作访问。 一个DynSequence对象的DynAny成分是序列的元素。 7.7.5 DynArray 一个DynArray对象代表一个数组。数组元素可以通过使用get和set操作访问。 一个DynArray对象的DynAny成分是数组的元素。 26 7.8 Any 和和和和 DnyAny 对象之间的转换对象之间的转换对象之间的转换对象之间的转换 DynAny接口定义了一些用来在Any对象和DynAny对象之间的转换方法。任何操作都要初始化拥有指 定的Any值的DynAny。如果Any的类型和DynAny的不匹配,将抛出TypeMismatch异常。通过任何操 作从一个DnyAny创建一个Any。 作为一个演示怎样使用这些操作的例子,可能有人想要动态改变一个构造类型的内容,例如struct,他 用一个Any来代表。 通过下面的步骤完成这个任务: 1. 使用DynAnyFactory::create dyn any的类型操作从结构的TypeCode构造一个DynStruct对象。 2. DynAnyu::from 任意操作被用来初始化带有Any值的DynStruct。 3. 现在,DynStruct的内容可以被访问和修改了。 4. 使用DynAny::to 任意操作可以创建一个代表修改过的结构的新Any。 7.9 更多例子更多例子更多例子更多例子 在JacORB的demo/dynany的目录中包含一些使用DynAny对象的例子代码。在JacORB-Test 的 org.jacorb.test.orb.dynany包中还有更多的例子代码。 27 8 接口仓库接口仓库接口仓库接口仓库 在CORBA中使用ORB的接口仓库(IR)组件来管理运行时的类型信息。它允许动态的调用、查看、修 改IDL中的类型信息,例如,查找一个对象支持何种操作。有些ORB也需要接口仓库来确认一个对象 是否是另一个对象的子类,但大多数的ORB都能不通过接口仓库,而使用IDL编译时产生的伺服程序 来获取这种类型信息。 本质上,接口仓库是一个提供获取类型信息的可以远程访问的CORBA对象。注意JacORB的接口仓库 只支持JDK1.2 或以上版本。 8.1 接口仓库中的类型信息接口仓库中的类型信息接口仓库中的类型信息接口仓库中的类型信息 接口仓库使用与IDL接口文件相对应的层次包含结构来管理类型信息:模块包含接口、结构、常数 等,接口包含异常、操作、常数等。下图显示了这种层次关系: 接口仓库的内部描述通过几种方式来标识。接口仓库中的每一个元素都有一个唯一的全名,这和IDL 接口文件中的名空间相对应。在模块M1 的子模块M2 中定义的接口I1 有一个命名为M1::M2::I1。接 口仓库也提供另一种更灵活的方式--接口仓库标识(RID)--来命名IDL接口文件的结构。有很多种不同 的RID格式,但每个接口仓库必须能够处理下面的这种格式,以"IDL:"为前缀,以一个版本号为后后 缀,例如:"IDL:jacorb/demo/grid:1.0",在分号之间的名称可以使用IDL编译器预处理指令 #pragma prefix和#pragma ID前之之,入入来下之之,将下前命下采的入 8.2 接口仓库设计接口仓库设计接口仓库设计接口仓库设计 在设计接口仓库时,我们的目标是充分利用Java反射API的功能,从而避免再自行定义一套IDL类型 描述的基础数据。另一种设计是将接口仓库作为IDL编译器的后台,但是我们不想引入这样的依赖 性,而想让接口仓库成为轻量级的仓库服务器。前一种设计是可以实现的,因为Java和CORBA对象 的类似性,从而可以在运行时取得IDL类型信息。由此看来,我们可以不依赖编译时的IDL接口文件 28 来获取类型信息。另外,这种实现最大的好处是避免了数据的冗余以及IDL接口文件与Java实现时导 致的数据不一致,因为Java类已经生成。 因此,接口仓库必须载入Java类,使用反射进行分析,生成相应的IDL类型信息。最后,接口仓库实 现了Java语言到IDL语言的反向对应,如下图所示,其中f-1 表示了语言的反向对应。 8.3 使用接口仓库使用接口仓库使用接口仓库使用接口仓库 ORB要能访问接口仓库,接口仓库服务进程必须已经启动。启动接口仓库命令如下: $ir /home/brose/classes /home/brose/public_html/IR Ref 第一个参数是包含class文件和包的目录,接口仓库从这里载入这些类,并认为是IDL编译器产生的 Java类,如果上一步成功,则生成相关IDL的类型信息。第二个参数指向IOR文件。 要查询接口仓库的内容,可以使用图形化的接口仓库浏览器或查询命令。首先,让我们查询一个指 定的ID,JacORB提供命令qir(query IR)来完成此功能: $qir IDL:raccoon/test/cyberchair/Paper:1.0 接口仓库返回InterfaceDef对象,qir分析此对象并输出如下结果: interface Paper { void read(out string arg_0); raccoon::test::cyberchair::Review getReview(in long arg_0); raccoon::test::cyberchair::Review submitReview( in string arg_0, in long a rg_1); void listReviews(out string arg_0); }; 启动接口仓库浏览器,使用以下命令: $irbrowser 下图为屏幕截图: 29 IDL编译器使用OMG标准的IDL/JAVA语言映射来生成Java类,但这些Java类并没有足够的信息来重 建原始的IDL接口描述。例如,无法判断一个接口是否是只读的,或者一个参数是传入类型还传入/ 传出类型的,而且,IDL的模块在Java中并没有明确的表述,因此要判断Java中一个目录是不是模块 并不很容易。由于以下原因,JacORB的IDL编译器使用-ir选项产生另外一些Java类来保存这些信息。 $idl -ir myIdlFile.idl 编译器产生的其他类包括: !_Xmodule.java对应IDL定义的模块X !YIRHelper.java对应IDL定义的接口Y 如果接口仓库服务进程没有找到这些额外产生的类,它不会产生任何描述。注意,IDL编译器不会更 改标准定义生成的Java文件,它只是生成一些额外的类。 在这些额外的类中,_Xmodule.java只包含在接口文件中定义的模块,而不会包含使命-d选项生 成的Java包,因此,这些目录中的类也不会被接口仓库服务分析。 当客户端对象调用get_interface()操作时,ORB查询接口仓库,返回一个描述接口的 InterfaceDef元对象,使用此对象可以查询更多的信息,如接口中的操作定义和属性定义等。 接口仓库也可以象其他的CORBA对象一样调用,使用lookup()或lookup_name()操作,单个容器的内 容也可以被显示出来。 接口仓库元对象提供更多的描述操作。对于一个InterfaceDef对象,可以查看它包含的其他元对 象(如OperationDef对象)。也可以直接获取结构描述对象InterfaceDescription或 FullInterfaceDescription,引下数数实实之功新数数,引。,FullInterfaceDescripti on找找对下下的的下一一,构,。务实实提最最。前提提数数入 30 9 JacORB 的小程序代理的小程序代理的小程序代理的小程序代理 JacORB1.0beta13 JacORB IIOP (Appligator)样 下下从后, 的的对下 下设。,名新下从最最设。 入。。从 最最设。,入 JacORB Java (Applets) Java Internet新前新 前现新 从最最 入实将, 现。最最新前命 前下以最 ()对下的命功新一接,构从最最将新功命下新的命 样找的命下下下从最最 功新一接入入入来下。。设 CORBA JacORB。,将从最最新功一接下新的命下 的的服入。。 下从最最设。,从最最下。。,,务 ,入受将入从最最设。现新新从最最下新的命,户户下。。从最最下下下一,入 9.1 使用小程序代理使用小程序代理使用小程序代理使用小程序代理 JacORB引下 从最最设。下户户理,新下从最最在入新前对下现。最最对数入入,因下因对下对来当 OR下。。入下的决后后名 B最jacorb.orb.ORB(java.applet.Applet, java.util.Properties)。 JacORB的应用程序读取本地的配置文件(如jacorb.properties)来获取命名服务的URL及其他一 些重要参数,而小程序则没有本地文件可言,但是有一个远程的:和小程序放在同一目录的配置文 件,注意文件名必须是jacorb.properties。 和命名服务一样,小程序代理将自己的IOR写入到文件,小程序获取小程序代理IOR的文件位置,可 以通过配置项 jacorb.ProxyServerURL 前之之,或命。。 入下。数JacorbProxyServerURL前之之入入入 JacORB basecode WEB "pr找。数该之之,或之之之之, ,新从最最构命下 新新命 下该新新入该找的下 oxy.ior" IOR下上来入 现找一。实之实jacorb.NameServerURL指向小程序所在主机,否则,在小程序使用命名服务时 会产生一个安全异常。 使用如下命令启动小程序代理: $appligator 第一个参数为端口号,第二个指定小程序代理写入IOR的文件。这个文件必须和上述配置项 jacorb.ProxyServerURL 的值一致。 9.1.1 使用步骤使用步骤使用步骤使用步骤 !使用 jacorb.orb.init(applet,properties) ORB applet pro后后名 ,之入 下从最最如初, perties新前下构 !,jacorb.properties文件放置在小程序所在目录 !使用配置项jacorb.ProxyServerURL IOR或从最最。数构命从最最设。下 上来 ! IOR ( )确一新的的的下 上来新前,从最最。。 新务对的命前 !新务对的命前,,从最最设。appligator,其中文件为小程序代理的IOR文 件 9.1.2 程序属性程序属性程序属性程序属性 如上所述,小程序有几种方式获取属性。最重要的属性是小程序代理的IOR文件URL,没有这个属 性,小程序将无法工作。如果使用命名服务,命名服务的IOR文件URL也必须设置。 属性可以通过以下三种方式设置: 31 !在ORB.init()时传递属性 !在配置文件jacorb.properties中定义 !小程序代理的IOR文件URL也可以在HTML文件中设置小程序的参数 9.1.3 小程序代理和小程序代理和小程序代理和小程序代理和 Netscpe/IE,,,,AppletViewer Netscape CORBA( ) JacORB Netscape CORBA如初对 册命一来下或入 自一,新。。 在现找自前 下 入,新 <命或新新 NS_ROOT>/java/classes iiop10.jar( )下新自前前下命一的的的 入的的,下下上来下最的 Netscape jacorb.jar找找下,,下,引下 ,。新新下下下下上来下入入,最, 上来采入。新新入入 入 Netscape ( Netscape Java )入 下入对之之下入或果请对新采一将 下新前实实 下 上。最入 ,找新,果命入 jar JacORB VisiBroker Netscape4.72 J入入,命找路下上来,样入入入入自前下下 命 下入上来入对对新 命 DK1.3 JacORB下的来前组功现新对 下从最最入 IE Netscape JDK1.3微微下 命 或微参最新。下下下下入,,微微微微对下。接入对对一微命微入。。 下 IE IE JacORB JacORB的来入下对插插 前。。 ,新,, 下入采新$WINNT\Java\TrustLib新新下入入 新前,jacorb.jar拷拷入。新新,最册的,或命新,jacorb, org或HTTPClient新新拷入。新新入 AppletViewer JacORB CORBA Sun CORBA从最最设。新 前功将将下实入新新,, 下 入设小 下 入入实将 。。前下新新前使使从最最最 $appletviewer http://www.example.com/CORBA/dii_example.html JacORB bin jacapplet appletviewer (新 下 新新入下对下的下 下在下最最,,,之之命最。 下。数 新,在找 JDK之入 下。数)入 入入新之如下如如服前。。从最最设。,或命为为或命下的服命。。从最最设。,一如如对对入 9.1.4 示例示例示例示例 新新新jacorb/demo/applet下下当下从最最下对下,命对下下或现。下对下,下下下下最。从最 html最下 上来入,现新下和对下,引,,新的的的,务,,从最最设。,,,现。使对下的的,, appletviewer Netscape/IE最找新前。。 或 前。。从最最对入 jacorb.properties jacorb.jar确一命新将确下新新下入 9.2 通过防火墙使用通过防火墙使用通过防火墙使用通过防火墙使用 JacORB 防防防实将因 JacORB功来当最两。接实两一一命两实微实两一一入 下下功下的。最最前册决下和功 JacORB HTTP GIOP HTTP下。将入 从最最设。新前。。。接受将,构 个为,的个新组 的前实实防防防 入 9.2.1 小程序代理小程序代理小程序代理小程序代理 从最最设。册决对从最最下小小受将入该小的下从最最新功一接入下新的命,下。命对新一在数下 CORBA GIOP CORBA功务服 现。入分。分新的入从最最设。下 设。,命一。从最最功一入以最对下 CORBA COR的的服前,引下,下下入 的的下一,下,实设。,构下下,,下数入,,实设。,服构 BA的的对从最最构服下户户下入 GIOP CORBA从最最设。,的新。或从最最,命新前实下 下设。,从最最设。下初下对下 对对,和新 C构命下。接。新,,,下下。。从最最设。下一,,,,指入找。接,入新前实之新防防防最指下 ORBA对对下实实从最最设。前。。一,入对下命下的的下对功实实防防防下一,命新防防防新达下 一,,下当新从最最设。下下对下下的的入 CORBA GIOP下对。。接实两防防防功。。 命 的,为为最为采务。为新防防防前一的对下新。下。接 ,。。。。接,,从最最设。入 32 CORB的新下下新防防防最指下的的服下新前实实从最最设。前现为入入入 AInter。。。,。。命或 net CORBA Netscape Internet前下 的的服,上上新前实实从最最设。入在在, ,自一样 前,最。。入 CORBA下对。 现。最最或的的功为为从最最设。,新,新实之上来入决加对下实之实入从最最当如 ,的。。从最最设。,入入入最现。最最,。。从最最设。,,实之实jacorb.use_appligator _for_applications设为 on off,入入如如找,从最最设。,将,前命实之实之下 ,对从最最,jacorb.use_appligator_ for_applets of之下 f入 IOR下最,现找构户从最最设。下命之,下命构命新的的的下的服对数最,从最最设。,,在, 下入 新新新。数构命下上来,下下上来为为新前,入。。从最最设。下。。。。。,新前。。命命上来 WEB IOR URL jacorb.ProxyServerURL下的服或。。 的的服,从最最设。下 上来为为命实之实 对将入 9.2.2 HTTP 隧道隧道隧道隧道 GIOP HTTP GIOP入入防防防。。实微实两命命和和来下实之组微微 的实实,新前实实 个为,的个新 HTTP JacORB HTTP HTTP1.1组的样构实实防防防入 达之 个为自一,一组 参服下数据的,新功新提最 HTTP ( CORBA CORBA ) HTTP ( CORB最。在,防防防最入下下通通下 一, 样 。。。入 的的服 命 ,当 样 A CORBA )的的服入 。。。 入 JacORB HTTP OMG JacORB JacO下 个为,命以最通通的功,引。新功。或 下。。。命的的服入为对下 RB HTTP IP的的服下,新理服实之构功将确。。数入下 实一,实之新。。。后组入新前,据 的命前实 HTTP HTTP HTTP之 个为,入入构命置的命新, 个为,将下下一,找的命下实一下,实实 个为后组入 IP在下 的命。多。功多,对入,之之实之实jacorb.use_httptunneling_for=192.168.0.1, 192.168.0.2 ,则所有到这两个主机的通信都使用HTTP隧道。 9.2.3 小程序代理和小程序代理和小程序代理和小程序代理和 HTTP 隧道隧道隧道隧道 因为小程序代理也是一个CORBA服务,所以它也支持HTTP隧道。不需要额外的配置小程序代理就可 以使用HTTP隧道来通过防火墙。 9.2.4 总结总结总结总结 !当防火墙只允许部分端口通过时,可以使用小程序代理作为GIOP代理 !让系统管理员配置一个防火墙允许通过的端口,如 7777,然后在该端口上启动小程序代理 $appligator 7777 Appligator_Ref !所有的CORBA对象都需要使用小程序代理来被防火墙外的客户访问或去访问防火墙外的其 他服务。在这些应用的配置文件中加入配置项 jacorb.use_appligator_for_applications=on。 !在客户端使用配置项jacorb.ProxyServerURL来设置小程序代理的IOR文件URL。 !使用配置项jacorb.use_httptunneling_for HTTP前之之新, 个为。。的命入 33 10 基于基于基于基于 SSL 的的的的 IIOP SSL,新,在找以最设。,找新前。。 前在。。。。和一客。。。命的的服新功下实一入,,新一接 SSL TCP层。。 设小对最,命将一接当一对和入 SSL JacORB新。。 新前,新,入入入入 ,。命自一加在入,新,实之对下。。或前一和加在在。入 SSL下一一,和实之 ,。入下之如对和来理,下和下当新下上的入入 10.1 重编译重编译重编译重编译 JacORB 安全库安全库安全库安全库 JacORB新通通下下入, 来下当当新采或下自一入引。,入新,,。。下新采或加入入入入入,,最 JacORB JacORB入入入入 入入入新采或该找入,将入入前最下 ,,,当当新采或下自一入 新入入新前,前下在来为为在,最 !JDK1.2或前前下下 ! IAIKs,。。 或在最 IAIK-JCE2.591或前前下下,。。。为http://jcewww.iaik.tu-graz.ac.at/ IsaSiLK 3.0或前前下下 ! Sun,。。 下或在最 JDK1.4 JSSE1.02 JDC ( JSSE1.02或 ,新前样 入下下 对或 ,。。新新src/org/jacorb/s ecurity/ssl/sun_jsse下上来README.jsse_1_0_2前入入 OpenSSL JacORB对或。。对务。,新,之如下的,入 样,册,对对 下现新 新新下新 JacORB ant下的和的的的置和找上的,,最新 下新新新新入新新 新新前入入入入入 10.2 配置配置配置配置 IAIK IAIK下上户户 下实之 10.2.1 设置设置设置设置 IAIK 证书库证书库证书库证书库 SSL X.509,依或参服下依对。。入下下。。新命将一接在。。,和。前一组当依在。。下在对入 下对这这命入最命命命一和下和。。入 Java2找找。。名下。。或下一一数据数数下接接入对下。。或找下一和依对依对。。或和找提对下 上来,,的的功,文。依对下之如。。入下下下加在数据。。在。一客,实实为的功新。。入 JacORB找找对下提提名下下下前命命命命实。。或,名新下。。务。服入。。命新前创一依对对、 /ks对依对功新小的、将入 将请。。、命通一以下在。入找入,,,。。务。服,新新新入 新新新新 ,,最新前。。提提名下的服对,或,从,下下。。或,或命命对下入下。。或入 ,,。。务。服,命命对下入下。。或,和命命和找下依对对或。。入样上来启启入对,入命新新 入命对下。。或,样对新启启入对,入命,命命对下入下依对对,下在,,,找找对下为的,和新 ,新入对下在。,对加在后决命依对命要新前。。要要之入入下提下使最 34 的新找下对对下新前。前在。下依对。。,通为。。下为的,,一和新。。入入因为任何人都能生 成这样的一个公钥证书,因此,收到证书的人要求此证书有自己信任的认证中心的数字签名。要签 名此证书,认证中心提供证书主题的标识声明。这个签名被信任,通常认证中心会审查需要签名的 公钥证书,甚至只签名自己发放的公钥证书。 为了使用方便,你可以自己充当认证中心,使用证书管理器导入证书,签名然后导出。原始的证书 库能重新导入这个经过某认证中心签名的证书。证书库有使用一个标准的链格式来存储公钥证书, 链的根证书就是在生成证书库时产生的证书。它自动地被私钥签名。链上的第二个证书就是被认证 中心签名的证书。链上的最后一个证书必须是认证中心的公钥证书,并被认证中心自己签名。 35 可以选择一个证书的别名,然后从钥匙菜单选择验证来验证此钥匙链的有效性。必须保证钥匙链的 格式正确,并且已经通过信任者菜单中加入认证中心为信任者,否则验证会失败。只有验证通过, 该公钥证书才被用于建立SSL连接。更多关于证书库的文档可以参看Sun工具keytool的相关文档。如 果你关心“真正”的安全性,在整个系统中使用一个管理认证中心是必要的。 10.2.2 一步一步生成证书一步一步生成证书一步一步生成证书一步一步生成证书 为了创建一个简单的证书体系,应按照如下步骤进行(括号中是管理器的菜单命令): 1.创建一个用户的证书库(File|New),生成认证中心和用户的公钥对(Keys|New) 2.打开该证书库(File|Open),选择并导出自签名用户证书(Certificates|Export) 3.打开认证中心的证书库,并将用户证书加入到信任者(Trustees|Add) 4.选定信任的用户证书,并生成一个签名的公钥证书(Certificates|Create)。保留角色名为空,并输入 私钥密码,点击OK生成证书。 5.导出认证中心自签名的证书。从认证中心的证书库中删除信任的证书(Trustees|Delete) 6.再次用户的证书库,导入认证中心已经签名的用户证书(Certificate|Import),并导入认证中心的公钥 证书。 7.将认证中心的公钥证书设为信任者。这只是为了验证链用,发布证书库并不需要。注意验证失败会 导致一个签名异常。 10.3 配置配置配置配置 SSL 的属性的属性的属性的属性 当ORB被应用初始化时,它从配置文件或命名行读入配置项。为了JacORB支持SSL,应设置以下配 置项:jacorb.security.support_ssl=on。这样,在启动时会载入SSL的相关类,通过不同的 配置项来配置SSL的其他信息。 正如在前面章节讲到的,加密数据(公钥对和证书)保存在证书库中,要配置证书库的文件名,需要设 置以下配置项:jacorb.security.keystore=AKeystoreFileName。 证书库文件可以是绝对路径,也可以相对于主目录的相关路径。ORB按上述方式搜索证书库,在找 到第一个证书库时停止搜索。如果该配置项没以设置,在ORB启动时会提示用户输入证书库的路 36 径。 为了避免输入很多别名和密码(一组用于证书库,每个证书也需要一组),可以使用以下配置项定义缺 省的别名和密码: # the name of the default key alias to look up in the keystore jacorb.security.default_user=brose jacorb.security.default_password=jacorb 可以进一步使用以下配置项来设置SSL: jacorb.security.ssl.client.supported_options=0 jacorb.security.ssl.client.required_options=0 jacorb.security.ssl.server.supported_options=0 jacorb.security.ssl.server.required_options=0 这些配置项的值是十六进制的掩码,每一位的含义在CORBA安全服务规范中定义,以下取自JacORB 的security.idl文件: typedef unsigned short AssociationOptions; const AssociationOptions NoProtection = 1; const AssociationOptions Integrity = 2; const AssociationOptions Confidentiality = 4; const AssociationOptions DetectReplay = 8; const AssociationOptions DetectMisordering = 16; const AssociationOptions EstablishTrustInTarget = 32; const AssociationOptions EstablishTrustInClient = 64; const AssociationOptions NoDelegation = 128; const AssociationOptions SimpleDelegation = 256; const AssociationOptions CompositeDelegation = 512; 10.3.1 客户端配置客户端配置客户端配置客户端配置 配置项jacorb.security.ssl.client.supported_options=20 表示客户端使用SSL。实际 上这是SSL的缺省配置,并且总是应该被客户端支持。 配置项jacorb.security.ssl.client.supported_options=40 表明客户端从自己的证书库 中载入公钥对和证书,因为客户端也要认证服务器。 配置项jacorb.security.ssl.client.required_options=20 表示强制使用SSL。 配置项jacorb.security.ssl.client.required_options=40 表示强制使用SSL。实际上此 项无意义,因为客户端无法强制服务器用SSL来认证它(也许服务器不支持SSL呢)。 10.3.2 服务器端配置服务器端配置服务器端配置服务器端配置 配置项jacorb.security.ssl.server.supported_options=1 向客户端表明服务器也支持 不保护的连接。如果设为此项,则required的配置项无须设置,因为此项设置将覆盖它们的设置。 配置项jacorb.security.ssl.server.supported_options=20 表明服务器支持SSL。实际 上这是缺省的SSL行为,并且总应该被服务器支持。这也使得服务器从证书库中载入公钥对及证书。 配置项jacorb.security.ssl.server.supported_options=40 被忽略,因为认证客户端要 么已经要求,要么不支持(不能由客户端来要求被认证)。 配置项jacorb.security.ssl.server.required_options=20 表示强制使用SSL。 配置项jacorb.security.ssl.server.required_options=40 表示强制使用SSL,并要认证 客户端。将从客户端获取证书进行认证。 37 11 双向双向双向双向 GIOP 双向GIOP主要用于小程序回调,或者有防火墙而不能直接访问目的主机时。例如,设想你想通过一 个小程序来监视服务器的运行,这通常是通过在服务器上注册的小程序回调对象来完成的,而不用 小程序时刻去查询服务器的事件。如果没有双向GIOP,要完成此功能,服务器必须新建一个到客户 端的连接,而这对小程序无效,因为小程序不能作为服务器(例如,新建ServerSocket)。双向GIOP能 起作用是因为它能重用小程序新建到服务器的连接来传递服务器到小程序的GIOP包(而这在标准 GIOP中是不可能的)。 11.1 设置双向设置双向设置双向设置双向 GIOP 设置双向GIOP包含以下两个步骤: 1.设置ORB的初始属性及双向策略 2.将双向策略加入到伺服程序的POA中 11.1.1 设置设置设置设置 ORB 初始属性初始属性初始属性初始属性 第一件事是要设置以下配置项: org.omg.PortableInterceptor.ORBInitializerClass.bidir_init=org.jacorb.or b.connection.BiDirConnectionInitializer 这样,在ORB启动时,相关策略工厂及解释器将被载入。 11.1.2 创建双向策略创建双向策略创建双向策略创建双向策略 通过策略工厂来创建双向策略: import org.omg.BiDirPolicy.*; import org.omg.CORBA.*; [...] Any any = orb.create_any(); BidirectionalPolicyValueHelper.insert( any, BOTH.value ); Policy p = orb.create_policy( BIDIRECTIONAL_POLICY_TYPE.value,any ); 新策略的值传递给工厂any,ORB使用指定类型和值来创建一个策略,此策略用于生成POA。注意如 果所有的POA都设置了此策略,则所有的连接都激活双向GIOP,甚至对于没有使用此策略的POA。 完整的源代码可以在demo目录下找到。 11.2 验证双向验证双向验证双向验证双向 GIOP 已经使用已经使用已经使用已经使用 在应用程序内部,可以判断连接是标准的还是双向的。要么通过网络监视工具,要么察看JacORB的 输出。 如果调试模式设为 2 或更高,服务器端以下输出表时连接被重用: [ ConnectionManager: found conn to target : ] 如果连接未被重用,则在客户端有如下输出: [ Opened new server-side TCP/IP transport to : ] 38 11.3 TAO 协同性协同性协同性协同性 在TAO和JacORB使用双向GIOP互操作时存在一个问题:如果JacORB使用IP地址作为主机名(JacORB 缺省情况),而TAO使用DNS名作为主机名(TAO缺省情况),从JacORB客户端到TAO服务器的连接不 能被重用。当然,如果二者使用同一格式的主机名,则能解决此问题。因此,有两种方法可以解决 此问题: 1.使用‘‘-ORBdotteddecimaladdresses 1’’作为TAO服务器的命令行参数 2.重新编译JacORB使其支持DNS(更多信息请察看安装文件) 39 12 可移植拦截器可移植拦截器可移植拦截器可移植拦截器-PI 从 1.1 版本开始JacORB支持可移植拦截器,其规范可参考http://cgi.omg.org/cgi-bin/doc?ptc/00-03-03 因此我们不提供PI的编程文档,而只是说明JacORB解决方案。 将拦截器集成进JacORB的第一步是通过以下格式的配置项注册拦截器: org.omg.PortableInterceptor.ORBInitializerClass.= 后缀仅用来区别不同的拦截器,而没有任何实际意义。配置项的值必须是拦截器的全类名(包含包)。 如果调试方式设置 2 或以上,当此类不在类路径中时JacORB会抛出一个类找不到的异常。 一个示例的配置如下: org.omg.PortableInterceptor.ORBInitializerClass.my_init= test.MyInterceptorInitializer 不过,规范不提供任何访问ORB的接口。如果你需要从拦截器外访问ORB,你需要将ORBInitInfo 对象强制转换为orb.portableInterceptor.ORBInitInfoImpl并调用getORB()方法来获取 ORB的引用。 当使用服务命名空间时,注意不要用java.lang.Integer.MAX_VALUE作为ID,应为此值已被内 部使用。另外,也要注意使用完或出现异常时关闭ORB。 40 13 JacORB 实用程序实用程序实用程序实用程序 本章介绍JacORB提供的实用程序,包括idl及命名服务。 13.1 IDL IDL编译器分析IDL接口文件并将期映射为Java类,IDL的接口翻译为Java的接口,其他各项也翻译为 对应的Java类。使用IDL编译器自动生成所有接口的桩和骨架。 用法 idl [-h|-help] [-v|-version] [-syntax] [-all] [-Idir] [- Dsymbol[=value]] [-d ] [-p ] [-i2jpackage ][-W debug level] -h | -help 显示用法帮助 -v | -version 显示版本信息 -noskel 禁止生成骨架文件 -ir 生成接口仓库需要的额外的文件,通常每个模块和接口各生成一个文件 -syntax 只进行语法检查,不生成文件 -all 也生成包含文件的代码,缺省条件下不生成 -I 指定搜索IDL文件的目录,缺省情况下只在当前目录搜索。 -D 定义编译器使用的符号,值缺省为 1。 -U 去掉符号定义。 -d 生成Java源文件的起始目录,缺省为当前目录。 -p 指定生成Java文件的包前缀,编译器会生成相应的目录结构。 -i2jpackage 将模块转定义为包。例如-i2jpackage X:a.b.c将模块X转化为包a.b.c,则模块X下 接口ident,编译后为a.b.c.ident IDL分析器使用Scott Hudson’s CUP CORBA LALR功分一组服一组, 接接上来下 分决新jacorb/Idl/parser.cup上来入命通入 13.2 ns JacORB找找新的的的,新的的 CORBA的下初,下通通下 的的,下实。对对的的上上入新的的的下第 接的的入 。决 $ ns [] 或 $ jaco jacorb.Naming.NameServer [] 对入 $ ns ~/public html/NS Ref 新的的的来下为的下。接。入 41 13.3 nmg JacORB新的的的务。服,提提名下务。下下入 。决 $nmg 13.4 lsns 列请该新的构功下下达功入新下,,在以和。或当,当当下的的后使使入-r对,达使数选使使入 。决 $lsns [-r] 使对 $lsns grid,新下 使对的的现新,和,在以入新的的的在使使最 /grid.service 13.5 dior IRO册。 实功功,。之新置理或命对和入 。决 $ dior | -f 使对 $ dior -f ~/public html/NS Ref ------IOR components----- TypeId : IDL:omg.org/CosNaming/NamingContextExt:1.0 Profile Id : TAG_INTERNET_IOP IIOP Version : 1.0 Host : 160.45.110.41 Port : 49435 Object key : 0x52 6F 6F 74 50 4F 41 3A 3A 30 D7 D1 91 E1 70 95 04 13.6 pingo ping对下对对命最下,和新,。新新当最。新下对对下non existent()方法。 用法 $ pingo | -f 13.7 ir 启动接口仓库 用法 42 $ ir 13.8 qir IDL命查接接或,新请入入一组下 。决 $ qir 13.9 ks ,,。。或务。服 。决 $ ks 43 14 配置清单配置清单配置清单配置清单 JacORB后完下 实之实或之的通完下达最 14.1 ORB 的配置的配置的配置的配置 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 ORBInitRef. 配置可以通过 ORB 的 resolve_intial_references 方法获 取的初始服务对象引用,支持文件和 HTTP 方式的 URL URL org.omg.PortableIntercep tor.ORBInitializer.Class . 拦截器的 Java 类名 类 jacorb.ProxyServerURL 小程序代理的 URL URL jacorb.orb.print_version JacORB 启动时是否显示版本号,缺省 为是 On/off jacorb.verbosity 调试模式 整型 jacorb.logfile 日志文件,缺省为标准输出 文件 jacorb.debug.dump_outgoi ng_messages 输出信息为十六进制格式,缺省为关闭 On/off jacorb.debug.dump_incomi ng_messages 输入信息为十六进制格式,缺省为关闭 On/off jacorb.giop_minor_versio n 最新的 GIOP 版本号,用于生成 IOR, 缺省为 2 整型 jacorb.retries 连接不能正常建立时的重试次数,缺省 为 5 整型 jacorb.retry_interval 重试之间的间隔,缺省为 500 毫秒 jacorb.outbuf_size 输出缓冲区的大小,缺省为 4096 字节 jacorb.maxManagedBufSize 这不是最大可用缓冲区的大小,而是最 大保留和管理的缓冲区的大小。这个值 会加上常数 5,因此真正原大小为 2*(5+maxSize-1)byte。当处理大的数据 结构时可以加大此值,减少此值保证大 的缓冲马上被释放。缺省为 18 整型 jacorb.connection.client _timeout 客户端超时,在请求阻塞多少时间后超 时。缺省不设置超时 毫秒 jacorb.connection.server _timeout 服务器保持空闲连接的最大时间。缺省 不设置超时 毫秒 jacorb.reference_caching 是否缓存对象引用。缺省不设置 On/off 44 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 jacorb.hashtable_class 指定用于引用缓存的哈希类, WeakHashtable 使用 WeakReferences,因此当只有哈希表中 引用时,可以被垃圾收集器,这对于大量 短生命周期的持久对象很有用。要求使用 JDK1.2 以上版本。而标准的 Hashtable 则会一直保留对象引用直至调用 _release()才显式删除 类 jacorb.use_bom 使用 GIOP1.2 字节顺序标记,从 CORBA2.4/2.5 起。缺省为关闭 On/off jacorb.giop.add_1_0_prof iles 加入额外的 IIOP1.0 说明,即使是使用 IIOP1.2。缺省为关闭 On/off org.omg.PortableIntercep tor.ORBInitializerClass. bidir_init 要支持双向 GIOP,此拦截器的设置。 缺省不设置 类 jacorb.ior_proxy_host 在 ServerSocket 不能访问时(如有防火墙 时),使用配置项 jacorb.ior_proxy_host 及 jacorb.ior_proxy_port 来告诉 ORB 应该包含什么 host/port 的 IOR。慎用此 选项,缺省无设置 主机 jacorb.ior_proxy_port 见上述 端口号 OAIAddr 对象适配器的 IP 地址,在有多个 IP 的 主机中使用此 IP 地址来生成对象引用。 注意 127.0.0.x 的只能被本机访问。缺省 无设置 主机 OAPort 见上述 端口号 jacorb.use_appligator 设置小程序是否使用小程序代理。缺省 为关闭 On/off org.omg.PortableIntercep tor.ORBInitializerClass. standard_init 标准拦截器,不要删除此配置项 类 14.2 POA 的配置的配置的配置的配置 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 jacorb.poa.monitoring 启动服务器的图形化监视器。缺省为关 闭 On/off jacorb.poa.thread_pool_m ax POA 线程池的最大值 整型 jacorb.poa.thread_pool_m in POA 线程池的最小值 整型 45 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 jacorb.poa.thread_priori ty 线程的优先级,如果不设置或设置错 误,使用最高优先级。缺省不设置 整型 jacorb.poa.queue_max 请求队例的长度。如果已经达到此值, 后续的请求将收到一个 Corba.TRANSIENT 异常。缺省为 100 整型 14.3 实现仓库的配置实现仓库的配置实现仓库的配置实现仓库的配置 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 jacorb.use_imr 是否服务启动时都和实现仓库通信。缺 省为关闭 On/off jacorb.imr.allow_auto_re gister 是否服务启动时自动注册到实现仓库。 缺省为关闭 On/off ORBInitRef.Implementatio nRepository 实现仓库的初始引用 URL jacorb.imr.table_file 实现仓库存储数据的文件 FILE jacorb.imr.backup_file 实现仓库备份数据的文件 FILE jacorb.imr.ior_file 实现仓库写入 IOR 的文件 FILE jacorb.imr.timeout 实现仓库等待服务注册的时间,超时的 服务被实现仓库认为启动失败。缺省为 2000 毫秒 jacorb.imr.no_of_poas 随实现仓库一起启动的 POA 数量,此 值用于优化内部数据存储,可以被超 过。缺省值为 100 整型 jacorb.imr.no_of_servers 随实现仓库一起启动的服务数量,此值 用于优化内部数据存储,可以被超过。 缺省值为 5 整型 jacorb.imr.connection_ti meout 实现仓库等待客户端连接的超时设置。 缺省为 2000 毫秒 jacorb.implname 持久服务的实现名,这是在实现仓库中 注册的服务名。 名 jacorb.java_exec 实现仓库启动的命令 命令字符串 14.4 安全的配置安全的配置安全的配置安全的配置 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 OASSLPort SSL 使用的端口号。缺省为动态分配 端口号 org.omg.PortableIntercep tor.ORBInitializerClass. 被要求使用 SSL 的可移植拦截器。缺省 无设置 类 46 配置项配置项配置项配置项 描述描述描述描述 类型类型类型类型 ForwardInit 无设置 jacorb.security.princi pal_authenticator 认证类的全名列表,以逗号分隔 类列表 jacorb.ssl.socket_factor y Socket 工厂类全名 类 jacorb.security.change_s sl_roles 交换客户端和服务器的角色以强制进行 客户端验证。注意,如果一方未实现此 功能,会带来一些问题。缺省为关闭 On/off jacorb.security.support_ ssl 是否启动 SSL。缺省为关闭 On/off jacorb.security.ssl.clie nt.supported_options SSL 客户端支持选项 整型 jacorb.security.ssl.clie nt.required_options SSL 客户端要求选项 整型 jacorb.security.ssl.serv er.supported_options SSL 服务器支持选项 整型 jacorb.security.ssl.serv er.required_options SSL 服务器要求选择 整型 jacorb.security.keystore 证书库的位置 FILE jacorb.security.keystore _password 证书库的口令 字符串 jacorb.security.trustees 受信任的认证中心公钥证书列表文件, 注意不设置,IAIK 认为所有认证中心签 名的证书都是正确的 文件 jacorb.security.default_ user 查找证书库时使用缺省别名 名字符串 jacorb.security.default_ password 上述别名的密码 字符串 jacorb.security.iaik_deb ug 是否输出 IAIK 的调试信息。缺省为关 闭 On/off jacorb.security.jsse.tru stees_from_ks Sun JSSE 设置:从证书库中取信任的认 证中心列表。缺省为关闭 On/off 47 15 缺陷和反馈缺陷和反馈缺陷和反馈缺陷和反馈 ()要缺列达 和,后完 1.IDL context入入服,自一数数 2.API上的或下上下,后完 bug下以最有有或 有如一,有来或brose@inf.fu-berlin.de bug入命在最对下入上下以最有有或 有如一,有来或hlstudio@sina.com,或进入 www.huihoo.com的论坛,关于JacORB的技术讨论也请访问该网站。 48 16 附录附录附录附录 [BVD01] Gerald Brose, Andreas Vogel, and Keith Duddy. Java Programming with CORBA. John Wiley& Sons, 3rd edition, 2001. [HV99] Michi Henning and Steve Vinoski. Advanced CORBA Programming with C++. Addison–Wesley, 1999. [OMG97] OMG. CORBAservices: Common Object Services Specification, November 1997. [Sie00] Jon Siegel. CORBA 3 Fundamentals and Programming. Wiley, 2nd edition, 2000. [Vin97] Steve Vinoski. Corba: Integrating diverse applications within distributed heterogeneous environments.IEEE Communications Magazine, 14(2), February 1997. [Vin98] Steve Vinoski. New features for corba 3.0. CACM, 41(10):44–52, October 1998.
还剩47页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 1 人已下载

下载pdf

pdf贡献者

summersky

贡献于2011-10-26

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!