JAVA&CORBA详解

Java IDL技术在Java平台上添加了CORBA(Common Object Request Broker Architecture)功能,提供了基于标准的互操作能力和连接性。Java IDL技术使得分布式的Java Web应用能够通过使用工业标准的IDL和IIOP(Internet Inter-ORB Protocol)来透明地调用远程网络服务的操作。运行时组件(Runtime Components)包括了一个用于分布式计算且使用IIOP通信的Java ORB.

可移植对象适配器(Portable Object Adapter,POA)
CORBA对象的负责分隔服务器端远程调用句柄(handler)到远程对象和它的服务者(servant)。对象由远程调用所暴露,而服务者包含实际处理这些请求的方法。每个对象都可以选择服务者为静态的(一次)或动态的(每个远程调用),在这两种情况下,都允许调用转移到另一台服务器。
在服务器端,POA形成了类似树状的结构,每个POA都负责一到多个服务的对象。树的分支可以是独立活动的、或钝化的,服务者调用有不同的代码和不同的请求处理策略。

API规范
    * org.omg.CORBA 包 - 提供了OMG CORBA APIs到Java编程语言的映射
    * org.omg.CosNaming 包 - 为Java IDL提供命名服务
    * org.omg.PortableServer 包 - 为建立服务器端的可移植的、跨越多ORB的应用程序提供类和接口
    * org.omg.PortableInterceptor 包 - 提供了注册ORB钩子的机制,此钩子通过ORB服务能截取正常的ORB执行流
    * org.omg.DynamicAny 包 - 提供了使得任何值都能被动态解释(或遍历)和通过DynAny对象构造出来的类和接口
    * org.omg.CORBA.ORB - 为CORBA ORB功能的API

分布式对象之间的关系有两方面:客户端和服务器。
服务器提供远程接口,客户端调用远程接口。
在客户端,应用程序包括远程对象的引用。该对象引用有stub方法,它是独立的远程方法。stub方法实际连接到ORB,因此调用它实际上转发调用到服务器。
在服务器端,ORB使用skeleton代码翻译远程调用为本地对象的方法调用。Skeleton把调用转换成指定实现的格式,并在方法中调用。当方法返回时,Skeleton代码转换方法调用的结果或错误,经ORB送回客户端。

Java IDL开发过程
1)定义远程接口
使用IDL语言为远程对象定义接口。
【Billing.idl源代码】如下:

  1. // 声明CORBA IDL模块  
  2. module BillingApp{  
  3.  // 声明接口  
  4.  interface Billing{  
  5.   string successBilling();  
  6.   oneway void shutdown();  
  7.  };  
  8. };   

2)编译远程接口
使用idlj编译器生成Java语言的stub和skeleton源文件。
idlj编译器缺省只生成客户端的binding代码。如果同时需要客户端的bindings和服务器端的skeletons,必须加上-fall选项。
使用POA(Portable Object Adaptor)的优点:
· 允许编程者构建对象在不同ORB产品之间的可移植实现
· 支持带持久化标识的对象
· 对对象的透明活动提供支持
· 允许单个servant支持多种对象同时标识
注意:确定jdk/bin目录下有:idlj、java、javac、orbd
命令:
 idlj -fall Billing.idl
在当前目录下生成BillingApp目录,包含如下六个文件:
· Billing.java    ————> 此接口包含IDL接口的Java版本。它继承自org.omg.CORBA.Object,提供标准的CORBA对象功能。
· BillingHelper.java    ————> 此类提供辅助功能,Helper类负责读写数据类型到CORBA流,以及插入和提取数据类型。
· BillingHolder.java    ————> This final class holds a public instance member of type Billing.
· BillingOperations.java    ————> 此接口包含successBilling()和shutdown()方法。
· BillingPOA.java    ————> 此抽象类是基于流的服务器Skeleton,为服务器提供基本的CORBA功能。它继承org.omg.PortableServer.Servant,实现了InvokeHandler接口和BillingOperations接口。服务器类BillingServant继承BillingPOA。
· _BillingStub.java    ————> 此类是客户端stub,为客户端提供CORBA功能。它继承org.omg.CORBA.Object,提供标准CORBA对象功能。还扩展了BillingOperations接口和org.omg.CORBA.portable.IDLEntity接口。

3)实现服务器端
一旦使用idlj编译器后,就可以使用它产生的Skeleton装配服务器应用程序了。另外要实现远程接口方法,服务器代码应包含启动ORB和等待远程客户端调用的机制。
服务器端由两个类组成,一个是servant,另一个是Server。
servant是BillingImpl类,是Billing IDL接口的实现,每个Billing实例均由BillingImpl实例实现。servant是BillingPOA的子类。
servant包含了IDL定义的所有方法,与通常的Java方法类似。
server类含服务器的main()方法,它:
· 创建和初始化ORB实例
· 获得根POA的引用并激活POAManager
· 创建一个Servant实例(CORBA的Billing对象的实现)并通知ORB
· 获得根命名上下文
· 在命名上下文用“Billing”名注册新对象
· 等待客户端调用此新对象

【BillingImpl.java源码】:

 

  1. 01.import org.omg.CORBA.ORB;     
  2. 02.import BillingApp.*;     
  3. 03.class BillingImpl extends BillingPOA{     
  4. 04private ORB orb;     
  5. 05public void setORB(ORB orb_val){     
  6. 06.  this.orb = orb_val;     
  7. 07. }     
  8. 08/**   
  9. 09.  * 实现successBilling()方法   
  10. 10.  */    
  11. 11public String successBilling() {     
  12. 12.  return "/nBilling success!!/n";     
  13. 13. }     
  14. 14/**   
  15. 15.  * 实现shutdown()方法   
  16. 16.  */    
  17. 17public void shutdown(){     
  18. 18.  orb.shutdown(false);     
  19. 19. }     
  20. 20.}    
  21. import org.omg.CORBA.ORB;  
  22. import BillingApp.*;  
  23. class BillingImpl extends BillingPOA{  
  24.  private ORB orb;  
  25.  public void setORB(ORB orb_val){  
  26.   this.orb = orb_val;  
  27.  }  
  28.  /** 
  29.   * 实现successBilling()方法 
  30.   */  
  31.  public String successBilling() {  
  32.   return "/nBilling success!!/n";  
  33.  }  
  34.  /** 
  35.   * 实现shutdown()方法 
  36.   */  
  37.  public void shutdown(){  
  38.   orb.shutdown(false);  
  39.  }  
  40. }  

【BillingServer.java源码】:

  1. view plaincopy to clipboardprint?  
  2. 01.import org.omg.CORBA.ORB;     
  3. 02.import org.omg.CosNaming.NameComponent;     
  4. 03.import org.omg.CosNaming.NamingContextExt;     
  5. 04.import org.omg.CosNaming.NamingContextExtHelper;     
  6. 05.import org.omg.PortableServer.POA;     
  7. 06.import BillingApp.*;     
  8. 07.public class BillingServer {     
  9. 08public static void main(String args[]){     
  10. 09.  try{     
  11. 10.   // 创建和初始化ORB     
  12. 11.   ORB orb = ORB.init(args, null);     
  13. 12.   // 获得根POA的引用并激活POAManager     
  14. 13.   POA rootpoa = (POA)orb.resolve_initial_references("RootPOA");     
  15. 14.   rootpoa.the_POAManager().activate();     
  16. 15.   // 创建servant并注册到ORB     
  17. 16.   BillingImpl billingImpl = new BillingImpl();     
  18. 17.   billingImpl.setORB(orb);     
  19. 18.   // 从servant获得对象引用     
  20. 19.   org.omg.CORBA.Object ref = rootpoa.servant_to_reference(billingImpl);     
  21. 20.   Billing href = BillingHelper.narrow(ref);     
  22. 21.   // 得到根命名上下文     
  23. 22.   org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");     
  24. 23.   // 使用命名上下文,它是互操作命名服务规范的一部分     
  25. 24.   NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);     
  26. 25.   // 在命名中绑定对象引用     
  27. 26.   String name = "Billing";     
  28. 27.   NameComponent path[] = ncRef.to_name(name);     
  29. 28.   ncRef.rebind(path, href);     
  30. 29.   System.out.println("BillingServer is ready and waiting...");     
  31. 30.   // 等待客户端调用     
  32. 31.   orb.run();     
  33. 32.  }catch(Exception e){     
  34. 33.   System.err.println("ERROR:"+e);     
  35. 34.   e.printStackTrace(System.out);     
  36. 35.  }     
  37. 36.  System.out.println("BillingServer Exiting ...");     
  38. 37. }     
  39. 38.}    
  40. import org.omg.CORBA.ORB;  
  41. import org.omg.CosNaming.NameComponent;  
  42. import org.omg.CosNaming.NamingContextExt;  
  43. import org.omg.CosNaming.NamingContextExtHelper;  
  44. import org.omg.PortableServer.POA;  
  45. import BillingApp.*;  
  46. public class BillingServer {  
  47.  public static void main(String args[]){  
  48.   try{  
  49.    // 创建和初始化ORB  
  50.    ORB orb = ORB.init(args, null);  
  51.    // 获得根POA的引用并激活POAManager  
  52.    POA rootpoa = (POA)orb.resolve_initial_references("RootPOA");  
  53.    rootpoa.the_POAManager().activate();  
  54.    // 创建servant并注册到ORB  
  55.    BillingImpl billingImpl = new BillingImpl();  
  56.    billingImpl.setORB(orb);  
  57.    // 从servant获得对象引用  
  58.    org.omg.CORBA.Object ref = rootpoa.servant_to_reference(billingImpl);  
  59.    Billing href = BillingHelper.narrow(ref);  
  60.    // 得到根命名上下文  
  61.    org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");  
  62.    // 使用命名上下文,它是互操作命名服务规范的一部分  
  63.    NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);  
  64.    // 在命名中绑定对象引用  
  65.    String name = "Billing";  
  66.    NameComponent path[] = ncRef.to_name(name);  
  67.    ncRef.rebind(path, href);  
  68.    System.out.println("BillingServer is ready and waiting...");  
  69.    // 等待客户端调用  
  70.    orb.run();  
  71.   }catch(Exception e){  
  72.    System.err.println("ERROR:"+e);  
  73.    e.printStackTrace(System.out);  
  74.   }  
  75.   System.out.println("BillingServer Exiting ...");  
  76.  }  
  77. }  
  

4)实现客户端
与第三步类似,可以使用idlj产生的stub作为客户端应用程序的基础。客户端代码建立于stub之上,启动ORB,使用服务器提供的命名服务查询,获得远程对象的引用,调用其方法。
【BillingClient.java源码】:

  1. 01.import org.omg.CORBA.ORB;     
  2. 02.import org.omg.CosNaming.NamingContextExt;     
  3. 03.import org.omg.CosNaming.NamingContextExtHelper;     
  4. 04.import BillingApp.*;     
  5. 05.public class BillingClient {     
  6. 06static Billing billingImpl;     
  7. 07public static void main(String args[]){     
  8. 08.  try{     
  9. 09.   // 创建和初始化ORB     
  10. 10.   ORB orb = ORB.init(args, null);     
  11. 11.   System.out.println("ORB initialised");     
  12. 12.   // 获得根命名上下文     
  13. 13.   org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");     
  14. 14.   // 使用NamingContextExt代替命名上下文,它是互操作命名服务的一部分     
  15. 15.   NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);     
  16. 16.   // 在命名中解析对象引用     
  17. 17.   String name = "Billing";     
  18. 18.   billingImpl = BillingHelper.narrow(ncRef.resolve_str(name));     
  19. 19.        
  20. 20.   System.out.println("Obtained a handle on server object: "+billingImpl);     
  21. 21.   System.out.println(billingImpl.successBilling());     
  22. 22.   billingImpl.shutdown();     
  23. 23.  }catch(Exception e){     
  24. 24.   System.out.println("ERROR: "+e);     
  25. 25.   e.printStackTrace(System.out);     
  26. 26.  }     
  27. 27. }     
  28. 28.}    
  29. import org.omg.CORBA.ORB;  
  30. import org.omg.CosNaming.NamingContextExt;  
  31. import org.omg.CosNaming.NamingContextExtHelper;  
  32. import BillingApp.*;  
  33. public class BillingClient {  
  34.  static Billing billingImpl;  
  35.  public static void main(String args[]){  
  36.   try{  
  37.    // 创建和初始化ORB  
  38.    ORB orb = ORB.init(args, null);  
  39.    System.out.println("ORB initialised");  
  40.    // 获得根命名上下文  
  41.    org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");  
  42.    // 使用NamingContextExt代替命名上下文,它是互操作命名服务的一部分  
  43.    NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);  
  44.    // 在命名中解析对象引用  
  45.    String name = "Billing";  
  46.    billingImpl = BillingHelper.narrow(ncRef.resolve_str(name));  
  47.      
  48.    System.out.println("Obtained a handle on server object: "+billingImpl);  
  49.    System.out.println(billingImpl.successBilling());  
  50.    billingImpl.shutdown();  
  51.   }catch(Exception e){  
  52.    System.out.println("ERROR: "+e);  
  53.    e.printStackTrace(System.out);  
  54.   }  
  55.  }  
  56. }  
  


5)启动应用程序
要运行服务器和客户端,必须先启动命名服务,再启动服务器,最后运行客户端。
此例用到命名服务,它使得servant对象的操作对客户端有效。服务器需要命名服务的对象引用,命名服务可以发布对象引用实现各种接口。客户端使用对象引用来调用方法。
Java SE 1.4以上提供了两种可选的命名服务:
· tnameserv
一种透明的命名服务
· orbd
包含自启动服务、透明的命名服务、持久化命名服务和命名管理器的后台处理进程。
本例使用orbd。

5.1)启动orbd
注意:Solaris系统运行要求root权限并以1024端口开始进程。因此,对所有OS,可以选用大于或等于1024的端口以实现统一。
-ORBInitialPort选项用于指定端口(非缺省状态)。
例如:假定使用1050端口的Java ORB Daemon(orbd),命令如下:
start orbd -ORBInitialPort 1050 -ORBInitialHost localhost

5.2)开始Billing服务器
java BillingServer -ORBInitialPort 1050 -ORBInitialHost localhost
注:如在同一台主机上运行,可省略-ORBInitialHost localhost

5.3)运行客户端应用程序
java BillingClient -ORBInitialPort 1050 -ORBInitialHost localhost


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值