基于Java IDL的分布式程序设计

  Java IDL介绍
  JavaIDL是Java 2开发平台中的CORBA功能扩展。在Java 2中引入JavaIDL,使得利用OMG IDL能够定义服务对象的基本功能,并且将IDL根据CORBA规范的要求,映射到Java语言,并以此开发出标准的具有互操作性和可连接性的分布式应用。JavaIDL使分布式、支持Web的Java应用可以基于IIOP协议透明地调用远程服务。
  JavaIDL运行期(Runtime)组件包括一个全兼容的对象请求代理——Java ORB,用于基于IIOP协议实现分布式对象之间的通信。该ORB支持瞬态CORBA对象和瞬态名字服务器,并且ORB生存期受运行ORB进程生存期的限制。
  在程序设计中,首先对要实现的服务对象功能进行系统分析,并创建IDL接口描述文件对功能进行描述。然后利用JavaIDL提供的IDL到Java语言的映射工具将IDL文件映射为客户端桩(Stub)文件和服务器骨架(Skeleton)文件。
  在实现的客户端应用程序中,包括对远程对象的引用、服务功能请求的发送以及服务对象返回结果的解析处理等功能。通常,客户端应用程序利用命名服务实现对远程对象的绑定,并通过客户端ORB将客户端与服务对象联系起来,实现方法的远程调用。
  在服务器端,ORB利用服务对象骨架将调用请求和参数的数据格式进行转换,把远程调用转换为对本地对象中方法的调用。当方法返回时,骨架对计算结果进行转换和封装,通过ORB把结果返回给客户机。
  建立CORBA应用程序的过程
  分布式应用程序设计的主要问题是确定建立在对象级上的客户与服务对象的关系,从其最根本的功能来讲,服务对象提供远程接口,客户对象调用远程接口,客户对象不需要了解远程CORBA对象的位置以及实现细节,也不需要了解哪个ORB用于对象之间的交互。
  按照实现的基本过程,CORBA对象服务的实现方式分为两种:对象的命名引用方式和字符串化对象引用方式。CORBA创建分布式应用程序的过程大体如下:
  ●进行系统分析,确定服务对象需要实现的功能;
  ●根据系统分析结果,编写IDL接口说明文件;
  ●编译接口说明文件,产生服务对象的骨架与客户对象的桩(可选);
  ●基于客户对象的桩,编写客户对象程序;
  ●基于服务对象的骨架或者动态请求实现,编写服务对象程序;
  ●分别编译客户对象和服务对象程序;
  ●启动服务对象程序;
  ●启动客户对象程序。
  分布式应用程序示例
  以下用一个例程说明建立分布式应用程序的过程:
  1.对象功能描述和系统简要设计
  在服务对象端将一个字符串对象赋值,客户端通过调用服务对象方法获取该字符串的值。根据对象功能的说明,用UML描述出服务对象需要实现的功能:
  getIt():String[]
  2.服务对象接口定义
  根据系统分析结果,用IDL编写出服务对象方法描述程序getMessage.idl:
  module getMessage
  {interface getIt
  {string returnObject();
  };
  };
  3.编译getMessage.idl
  idltojava-fno-cpp getMessage.idl。
  4.编写客户端程序
  //引入相关类库
  import org.omg.CosNaming.*;
  import org.omg.CORBA.*;
  //客户端对象方法
  public class client
  {public static void main(String args[])
  {//创建和初始化ORB
  ORB orb=ORB.init(args,null);
  //获取根命名服务上下文对象
  org.omg.CORBA.Object naming=
  orb.resolve_initial_references(“NameService”);
  NamingContext namingContext=NamingContextHelper.narrow(naming);
  //解析命名中的对象引用
  NameComponent nc=new NameComponent(“getMessage”,“”);
  NameComponent path[]={nc};
  getMessage.getIt method=getMessage-
  Helper.narrow(namingContext.resolve(path));
  //调用服务对象方法
  String result=method.returnObject();
  }
  }
  5.编写服务对象程序
  //引入相关类库
  import org.omg.CosNaming.*;
  import org.omg.CosNaming.NamingContext
  Package.*;
  import org.omg.CORBA.*;
  //服务方法
  class returnMethod extends _getMessage-
  ImplBase
  {public String getIt()
  {String result=“How about it”;
  return result;
  }
  }
  //服务器端方法
  public class server
  {public static void main(String args[])
  {//创建和初始化ORB
  ORB orb=ORB.init(args,null);
  //创建服务对象并将其向ORB注册
  returnMethod obj=new returnMethod();
  orb.connect(returnMethod);
  //获取根命名上下文
  org.omg.CORBA.Object objRef=
  orb.resolve_initial_references
  (“NameService”);
  NamingContext ncRef=Naming
  ContextHelper.narrow(objRef);
  //绑定命名中的对象引用
  NameComponent nc=new NameComponent(“getMessage”,“”);
  NameComponent path[]={nc};
  ncRef.rebind(path,objRef);
  //等待来自客户机的调用
  java.lang.Object sync=new java.lang
  .Object();
  synchronized(sync)
  {sync.wait();
  }
  }
  }
  6.分别编译服务器端和客户端程序
  (1)编译服务器端程序:
  javac getMessage\server.java
  (2)编译客户端程序:
  javac getMessage\client.java
  7.运行
  (1)打开一个仿真终端窗口,启动命名服务,其中3388为通信端口号:
  tnameserv-ORBInitialPort 3388
  (2)在另一个窗口中输入以下命令,运行服务端程序:
  java server-ORBInitialPort 3388
  (3)在另一个窗口中输入以下命令,运行客户端程序:
  java client-ORBInitialPort 3388