ORBD名称服务
CORBA通用对象服务(或称COS名称服务)提供了对象引用的树型目录,就像文件系统提供的文件目录一样。在JDK的早期版本中由tnameserv提供类似服务。tnameserv是暂时名称服务,只有在运行时才能维持名称上下文。如果关闭名称服务,那么所有的名称索引都会消失。J2SE1.4中为了保持和先前版本的通用性仍然保留了tnameserv。 
J2SE1.4的orbd(ORB后台服务)服务提供了暂时和永久名称服务。这两种服务都是对COS名称服务的实现。与暂时名称服务不同,永久名称服务提供了对名称索引的永久保存。也就是说,即使ORBD重启了,永久名称服务会自动恢复所有的名称索引内容。 
客户端与服务端都需要再获取根名称索引后才能启动。这能通过下面的代码实现: 
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameServce"); 
NamingContextExt ctx = NamingContextExtHelper.narrow(objRef); 
如果你使用J2SE1.4之前的tnameserv提供暂时名称服务,上面代码首行返回对暂时名称服务的对象引用。对象引用objRef是个通用CORBA对象,为了要能把它作为NamingContextExt对象使用,你必须要将它转换成合适的类型。在CORBA中需使用方法narrow来实现这个转换。另外,如果你在J2SE1.4中使用orbd,那么以上代码返回的就是对永久名称服务的对象引用。如果你想要在orbd中指明使用暂时名称服务,那么就要使用参数TNameService而不是NameService: 
org.omg.CORBA.Object objRef = orb.resolve_initial_references("TNameServce"); 
NamingContextExt ctx = NamingContextExtHelper.narrow(objRef); 
NamingContextExt和NamingContextExtHelper是在J2SE1.4中新添加的类。它们是共用名称服务(INS)的扩展,是基于CORBA名称服务的使用URL进行访问的名称系统,它们使用共同的引导程序并且共享一个通用初始名称索引。INS是COS名称服务的一个扩展,它提供了以下的几个新特性: 
n         解析使用的字符名称(如Company/Department/HumanResources/Expenses)。 
n         CORBA对象引用的URL(corbaloc: 和 corbaname: 格式)。 
n         NamingContextExt中包含了可用于CosName、URL和String之间转换的标准API函数。 
INS可使用如下的字符对象引用格式: 
1.通用对象引用(IOR):它是ORB能够解析的对象引用,能够通过通用ORB协议和网际ORB协议进行交互操作。客户端可以使用orb.object_to_string(objRef)方法获取对象引用。 
2.可供阅读的URL格式:corbaloc和corbaname提供CORBA对象的URL地址。corbaloc不需通过名称服务就可以被解析并指定对应的CORBA服务;corbaname能从一个特定的名称索引中解析出字符名称。如下列代码: 
corbaloc:iiop:[email protected]:3000/TraderService 
上面的代码说明如何从主机SomeDomain.com的3000端口上获取对TraderService的对象引用。 
再看这些代码: 
corbaname::SomeDomain.com:4000#conference/speakers 
上述代码从根名称上下文中解析出字符名称。在这个示例中通过URL定位名称服务然后解析名称conference/speakers。SomDomain.com是主机名,端口号是4000。 
数组相加:永久服务
现在我们来看如何开发一个永久性服务,其中的对象即使在创建它的进程已经中止的情况下仍可存在。同样我们也要遵从和前例一样的步骤进行开发:编写IDL接口,实现该接口,开发服务端和客户端程序。 
本例中我们将使用和前例一样的IDL接口即Add.idl文件。 
使用idlj编译器编译Add.idl接口。 
prompt> idlj -fall Add.idl 
该命令生成了客户端和服务端框架。 
下一步就是实现接口。实现过程与示例代码2中类似。但是在此我们把该实现命名为AddServant。该文件示例如代码5所示。 
代码示例5:AddServant.java  
import ArithApp.*; 
import org.omg.CORBA.ORB; 
  
class AddServant extends AddPOA { 
  
  private ORB orb; 
  
  public AddServant(ORB orb) { 
    this.orb = orb;  
  } 
     
  // implement the addArrays() method 
  public void addArrays(int a[], int b[],  
    ArithApp.AddPackage.arrayHolder result) { 
    result.value = new int[ArithApp.Add.SIZE]; 
    for(int i=0; i<ArithApp.Add.SIZE; i++) { 
      result.value[i] = a[i] + b[i]; 
    } 
  } 
} 
下面实现该永久服务端。实现如代码6。服务端完成下列任务: 
n         创建和初始化一个ORB实例。 
n         创建一个服务端。 
n         获得对根POA的引用。 
n         定义策略,指定该服务端是永久性的。 
n         创建一个永久POA。 
n         激活该永久POA的POAManager。 
n         将服务端与永久POA关联。 
n         获取对根名称索引的CORBA对象引用,然后在AddServer下注册该对象引用。 
n         等待客户的调用请求。 
代码示例6:AddServer3.java  
import ArithApp.*; 
import org.omg.CORBA.ORB; 
import org.omg.CORBA.Object; 
import org.omg.CosNaming.NameComponent; 
import org.omg.CosNaming.NamingContextExt; 
import org.omg.CosNaming.NamingContextExtHelper; 
import org.omg.CORBA.Policy; 
import org.omg.PortableServer.Servant; 
import org.omg.PortableServer.*; 
import org.omg.PortableServer.POA; 
  
public class AddServer3 { 
  
  public static void main(String args[]) { 
    try { 
      // create and initialize the ORB 
      ORB orb = ORB.init(args, null); 
  
      // create servant and instantiate it 
      AddServant servant = new AddServant(orb); 
  
      // get reference to rootpoa and activate the POAManager 
      POA rootpoa = POAHelper.narrow( 
        orb.resolve_initial_references("RootPOA")); 
      
      // Create the Persistent Policy 
      Policy[] policy = new Policy[1]; 
      policy[0] = rootpoa.create_lifespan_policy( 
        LifespanPolicyValue.PERSISTENT); 
  
      // Create a persistent POA by passing the policy 
      POA poa = rootpoa.create_POA("childPOA", null, policy );  
  
      // Activate PersistentPOA's POAManager. Without this 
      // all calls to persistent server will hang  
      // because POAManager 
      // will be in the 'HOLD' state. 
      poa.the_POAManager().activate( ); 
  
      // Associate the servant with PersistentPOA 
      poa.activate_object( servant ); 
  
      // Resolve RootNaming context and bind a name  
      // for the servant. 
      // "NameService" is used here....persistent name service. 
      org.omg.CORBA.Object obj =  
        orb.resolve_initial_references("NameService" ); 
      NamingContextExt rootContext =  
        NamingContextExtHelper.narrow(obj); 
  
      //bind the object reference in the naming context 
      NameComponent[] nc =  
        rootContext.to_name("AddServer"); 
      rootContext.rebind(nc, poa.servant_to_reference(servant)); 
  
      // wait for client requests 
      orb.run(); 
    } catch (Exception e) { 
       System.err.println("Exception  
         in AddServer3 Startup " + e); 
    } 
  } 
}  
 
  |