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:1.2@SomeDomain.com: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);
}
}
}