Chinaunix首页 | 论坛 | 博客
  • 博客访问: 900110
  • 博文数量: 322
  • 博客积分: 6688
  • 博客等级: 准将
  • 技术积分: 3626
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-19 11:26
文章分类

全部博文(322)

文章存档

2013年(5)

2012年(66)

2011年(87)

2010年(164)

分类: Java

2010-11-04 18:02:30

JAVA还提供了对CORBA(Common Object Request Broker Architecture,通用对象请求代理体系结构)的支持。CORBA是分布式对象系统的一个标准,它由OMG(Ojbect Management Group,对象管理组)制定。CORBA包含了几个规范,来说明分布式系统的不同侧面,例如:IIOP(Internet Inter-Orb Protocol, Internet对象请求代理间协议)网络协议规范,定义了客户和服务器如何进行通信;COSNaming规范,定义了如何进行命名;还有OMG IDL,定义了描述对象接口,以便能够产生可以与他们交流的代理方式。CORBA还有很多这样的规范,每一个都覆盖分布式系统中需要定义的一部分。 CORBA是平台和语言独立的,这意味着它不依赖于任何语言,也不依赖于任何操作系统。下面我们概略的介绍IDL技术,以及JAVA对该技术的支持。

   IDL技术概述
   IDL 是Interface Definition Language(接口定义语言)的缩写,是OMG定义的标准语言,用于定义所有 CORBA 对象的接口。IDL接口将声明一批操作、异常和属性。每个操作都有一个用法说明。用法说明定义了操作的名称、参数、结果和异常。OMG IDL不包括操作的实现;相反,正如其名称所示,它只是一种用来定义接口的语言。IDL的完整句法和语义在 OMG 规范的第 3 章中进行讨论,可在 OMG 站点找到,地址是http://www.omg.org/technology/documents/idl2x_spec_catalog.htm。使用Java(TM)编写的API提供基于标准的和CORBA的交互性和连接性。
   JAVA IDL的语法和使用
   下面我们学习怎么写一个最简单的IDL文件,文件名称是hello.idl。代码如下:
Java代码
  1.    module cn{   
  2.        interface Hello{   
  3.            string say();   
  4.        };   
  5.    };  

   结尾处的;不可省略。module相当与定义java的包,这里包名是cn,包名中不能包含.。interface用来定义接口,接口的名字是Hello。接口包含了一个方法,返回一个字符串。IDL中的字符串类型是string。对于基本数据类型而言,CORBA会选取语言定义更短的,这是IDL为了实现跨语言应用而不得不采取的折中。四、五两行大括号后面的;不可省略。
   接下来的工作,就是把这个idl文件编译成对应的java文件,这是通过JDK自带的idlj工具完成的,这个工具和javac在一个目录下。它的命令格式如下:
   idlj hello.idl
   我们可以使用-td参数指定生成java文件的路径,我的java文件所在的路径在在当前工程下的src中。我们可以指定生成文件的范围,比如只生成服务器端的文件,我们用-fserver命令行参数,如果只生成客户端的文件,使用-fserver参数,全部生成使用-fall参数。默认全部生成。在src 目录下,我们会发现新生成了一个目录cn,下面包含了6个java源文件,分述如下:
  • HelloPOA POA指的是Portable Object Adapter(轻便对象适配器)。这个抽象类是一个基于流的服务器端骨架,提供了服务器端基本的CORBA功能。
  • _HelloSutb 客户端的存根类,为客户端提供了CORBA功能。
  • Hello 这是java版的Hello接口,它提供了标准的CORBA对象功能。
  • HelloHelper 这是一个辅助类,负责向CORBA流中写入或读取对象。
  • HelloHolder 这是一个final类,它持有一个public的Hello实例变量。它用来操作CORBA输入输出流的参数。
  • HelloOperations 这个类才是我们所预想的那个接口,只包含我们定义的那个方法,不包含CORBA的任何东西。

   关于这些类的更详细的信息,读者可以参阅SUN公司发布的JavaDocs文档,里面有更详细的说明,还有更多的例子。
   现在我们提供一个服务器端的实现,注意这个实现类继承的是HelloPOA:
Java代码
  1. package cn.zxm.corba.hello.server;   
  2.   
  3. import cn.HelloPOA;   
  4.   
  5. public class HelloImpl extends HelloPOA {   
  6.     public String say() {   
  7.         System.out.println("客户调用时间——" + new java.util.Date());   
  8.         return "Hello World!";   
  9.     }   
  10. }  

   接下来,把它绑定到命名服务,以便客户端可以调用:
Java代码
  1. package cn.zxm.corba.hello.server;   
  2.   
  3. import java.util.Properties;   
  4.   
  5. import org.omg.CORBA.ORB;   
  6. import org.omg.CosNaming.NameComponent;   
  7. import org.omg.CosNaming.NamingContextExt;   
  8. import org.omg.CosNaming.NamingContextExtHelper;   
  9. import org.omg.PortableServer.POA;   
  10. import org.omg.PortableServer.POAHelper;   
  11.   
  12. import cn.Hello;   
  13. import cn.HelloHelper;   
  14.   
  15. public class HelloServer {   
  16.     public void run(String[] args) throws Exception {   
  17.         //生成一个对象请求代理(ORB),并初始化   
  18.         Properties props = new Properties();   
  19.         //初始化端口,默认的端口是900   
  20.         props.put("org.omg.CORBA.ORBInitialPort""1050");   
  21.         //绑定到服务器   
  22.         props.put("org.omg.CORBA.ORBInitialHost""192.168.1.100");   
  23.         //初始化ORB   
  24.         ORB orb = ORB.init(args, props);   
  25.         // get reference to rootpoa & activate the POAManager   
  26.         //获取一个根POA引用,并激活POA管理器   
  27.         POA poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));   
  28.         poa.the_POAManager().activate();   
  29.         //实例化一个HelloImpl对象   
  30.         HelloImpl hello = new HelloImpl();   
  31.         // 从servant获得一个对象引用   
  32.         org.omg.CORBA.Object ref = poa.servant_to_reference(hello);   
  33.         Hello href = HelloHelper.narrow(ref);   
  34.         // 获得命名上下文   
  35.         org.omg.CORBA.Object objref = orb.resolve_initial_references("NameService");   
  36.         // 使用NamingContextExt 它是INS(Interoperable Naming Service,协同命名规范)的一部分   
  37.         NamingContextExt ncRef = NamingContextExtHelper.narrow(objref);   
  38.         //绑定一个对象引用,以便客户端可以调用   
  39.         String name = "Hello";   
  40.         NameComponent[] nc = ncRef.to_name(name);   
  41.         ncRef.rebind(nc, href);   
  42.         System.out.println("HelloServer ready and waiting......");   
  43.         //运行ORB   
  44.         orb.run();   
  45.     }   
  46.        
  47.     public static void main(String[] args) {   
  48.         HelloServer server = new HelloServer();   
  49.         try {   
  50.             server.run(args);   
  51.         }catch(Exception e) {   
  52.             e.printStackTrace();   
  53.         }   
  54.     }   
  55. }  

   现在我们可以写客户端调用代码,代码如下:
Java代码
  1. package cn.zxm.corba.hello.client;   
  2.   
  3. import java.util.Properties;   
  4.   
  5. import org.omg.CORBA.ORB;   
  6. import org.omg.CosNaming.NamingContextExt;   
  7. import org.omg.CosNaming.NamingContextExtHelper;   
  8.   
  9. import cn.Hello;   
  10. import cn.HelloHelper;   
  11.   
  12. public class HelloClient {   
  13.     public void run(String[] args) throws Exception {   
  14.         Properties props = new Properties();   
  15.         // 生成一个ORB,并初始化,这个和Server端一样   
  16.         props .put("org.omg.CORBA.ORBInitialPort""1050");   
  17.         props.put("org.omg.CORBA.ORBInitialHost""192.168.1.100");   
  18.         ORB orb = ORB.init(args, props);   
  19.         // 获得根命名上下文   
  20.         org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");   
  21.         // 用NamingContextExt代替NamingContext.   
  22.         NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);   
  23.   
  24.         // 通过名称获取服务器端的对象引用   
  25.         String name = "Hello";   
  26.         Hello hello = HelloHelper.narrow(ncRef.resolve_str(name));   
  27.   
  28.         //调用远程对象   
  29.         System.out.println(hello.say());   
  30.     }   
  31.   
  32.     public static void main(String[] args) {   
  33.         HelloClient client = new HelloClient();   
  34.         try {   
  35.             client.run(args);   
  36.         } catch (Exception e) {   
  37.             e.printStackTrace();   
  38.         }   
  39.     }   
  40. }  

   一个完整的基于java的CORBA应用完成了,现在我们编译这些类了。编译完成后,我们需要启动orbd,这是一个类似于rmiregistry的工具,提供最简单的命名服务。启动的命令如下:
   start orbd -port 1050 -ORBInitialPort 1049 -ORBInitialHost localhost
这个命令定义了CORBA用到的服务器是本机,初始化端口是1049,使用的绑定端口是1050。然后我们运行HelloServer,命令是
   start java cn.zxm.corba.hello.server.HelloServer
   服务器会把_HelloStub绑定到orbd,我们使用的绑定名称是Hello。然后运行客户端,命令是
   java cn.zxm.corba.hello.client.HelloClient
运行效果如图1: 

图1 CORBA客户端运行效果

   通过上面的例子,我们对CORBA有了一个初步的印象。CORBA本身是极为复杂的,读者可以看到,上面的绑定和调用都是很繁琐的,而且让人难于理解。总体而言,它比RMI要复杂的多,因此,我们可以借助于RMI的简易性来实现CORBA。对分布式应用感兴趣的朋友,可以到OMG或者SUN的网站上,察看关于它的更详细的信息。
阅读(630) | 评论(1) | 转发(0) |
0

上一篇:CORBA简介

下一篇:CORBA

给主人留下些什么吧!~~

chinaunix网友2010-11-05 16:52:59

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com