服务器代码

服务器应用程序必须创建远程对象的实例并在命名服务中发布该实例。 Java™ 命名和目录接口 (JNDI) 定义了一组标准接口。 这些接口可用于查询命名服务或将对象绑定到该服务。

命名服务的实现可以是公共对象请求代理体系结构(CORBA)环境中的 CosNaming 服务。 CosNaming 服务是命名服务的集合,并作为由 CORBA 定义的一组接口被实现。 或者,命名服务可以通过使用 RMI(JRMP) 应用程序的远程方法调用(RMI)注册程序实现。 可以在 CORBA 和 RMI 情况下使用 JNDI。 这样做的效果是:使服务器实现独立于所使用的命名服务。 例如,您可以使用以下代码来获取命名服务并在其中绑定对象引用:
Context ctx = new InitialContext(...); 	// get hold of the initial context 
ctx.bind("sample", sampleReference);		// bind the reference to the name "sample"	 	
Object obj = ctx.lookup("sample");		// obtain the reference
要告知应用程序正在使用哪个命名实现,必须设置下列其中一个 Java 属性:
java.naming.factory.initial
还被定义为 javax.naming.Context.INITIAL_CONTEXT_FACTORY,此属性可指定命名服务提供程序的初始上下文工厂的类名。 对于 RMI 注册程序,该类名为 com.sun.jndi.rmi.registry.RegistryContextFactory。 对于 CosNaming 服务,类名为 com.sun.jndi.cosnaming.CNCtxFactory
java.naming.provider.url
此属性可配置根命名上下文和/或对象请求代理(ORB)。 当命名服务存储在不同的主机中时将使用此属性,此属性可以指定多种 URI 模式:
  • rmi
  • corbaname
  • corbaloc
  • IOR
  • iiop
  • iiopname
例如:
rmi://[<host>[:<port>]][/<initial_context>] for RMI registry    
iiop://[<host>[:<port>]][/<cosnaming_name>] for COSNaming
要在环境中获取上述属性,可以使用以下代码:
Hashtable env = new Hashtable(); 	
Env.put(Context.INITIAL_CONTEXT_FACTORY, 		
       "com.sun.jndi.cosnaming.CNCtxFactory");
然后将散列表作为参数传递到 InitialContext 的构造函数。

例如,使用 RMI(JRMP) 时,创建服务方实例,并按照上述步骤在命名服务中绑定此引用。

但是,使用 CORBA (Java IDL) 时,您必须执行一些额外的工作,因为您必须创建 ORB。 ORB 必须使服务方引用可用于远程调用。 此机制通常由 ORB 的对象适配器来控制。
public class Server {
	public static void main (String args []) {
		try {
			ORB orb = ORB.init(args, null);
			
			// Get reference to the root poa & activate the POAManager 
			POA poa = (POA)orb.resolve_initial_references("RootPOA"); 
			poa.the_POAManager().activate(); 
			
			// Create a servant and register with the ORB
			SampleImpl sample = new SampleImpl();			
			sample.setORB(orb); 

			// TIE model ONLY
			// create a tie, with servant being the delegate and
			// obtain the reference ref for the tie
			SamplePOATie tie = new SamplePOATie(sample, poa); 
			Sample ref = tie._this(orb);

			// Inheritance model ONLY
			// get object reference from the servant 
			org.omg.CORBA.Object ref = poa.servant_to_reference(sample);
      Sample ref = SampleHelper.narrow(ref);

			// bind the object reference ref to the naming service using JNDI
	   		..........(see previous code) .....
			orb.run();
		}
		catch(Exception e) {}
	}
}
对于 RMI-IIOP:
public class Server {
	public static void main (String args []) {
		try {
			ORB orb = ORB.init(args, null);
			
			// Get reference to the root poa & activate the POAManager 
			POA poa = (POA)orb.resolve_initial_references("RootPOA"); 
			poa.the_POAManager().activate();

			// Create servant and its tie
			SampleImpl sample = new SampleImpl();
			_SampleImpl_Tie tie = (_SampleImpl_Tie)Util.getTie(sample); 
			
			// get an usable object reference 
			org.omg.CORBA.Object ref = poa.servant_to_reference((Servant)tie);

			// bind the object reference ref to the naming service using JNDI
	   		..........(see previous code) .....
		}
		catch(Exception e) {}
	}
}

要使用上述可移植对象适配器(POA)服务器代码,必须同时使用 -iiop -poa 选项以使 rmic 能够生成联系。 如果不使用 POA,那么可以减少 RMI(IIOP) 服务器代码以实例化服务方 (SampleImpl sample = new SampleImpl())。然后,按照通常在 RMI(JRMP) 环境中执行的相同方式将服务方绑定到命名服务。 在这种情况下,您只需要使用 -iiop 选项,以使 rmic 能够生成 RMI-IIOP 联系。 如果省略 -iiop,那么将生成 RMI(JRMP) 框架。

在导出服务器上的 RMI-IIOP 对象时,不一定要在 JRMP 和 IIOP 之间进行选择。 如果需要单个服务器对象以支持 JRMP 和 IIOP 客户机,那么可以将 RMI-IIOP 对象同时导出到 JRMP 和 IIOP。 在 RMI-IIOP 术语中,此操作被称为双导出

RMI 客户机示例:
public class SampleClient { 	 
  public static void main(String [] args) {  	    
    try{ 			 		
      Sample sampleref
      //Look-up the naming service using JNDI and get the reference 			
            ......... 		
      // Invoke method   		
      System.out.println(sampleRef.message()); 	    
    } 	    
    catch(Exception e) {} 	  
  } 	
}  
CORBA 客户机示例:
public class SampleClient {
	public static void main (String [] args) {
		try {
			ORB orb = ORB.init(args, null);
			// Look up the naming service using JNDI
			......
			// Narrowing the reference to the correct class
			Sample sampleRef = SampleHelper.narrow(o);
			// Method Invocation
			System.out.println(sampleRef.message());
		}
		catch(Exception e) {}
	}
}
RMI-IIOP 客户机示例:
public class SampleClient {
	public static void main (String [] args) {
		try{
			ORB orb = ORB.init(args, null);
			// Retrieving reference from naming service
			........
			// Narrowing the reference to the correct class
			Sample sampleRef = (Sample)PortableRemoteObject.narrow(o, Sample.class);
			// Method Invocation
			System.out.println(sampleRef.message());
		}
		catch(Exception e) {}
	}
}