Java IDL入门

本文翻译自:

Getting Started with Java IDL

Java IDL是一种分布式对象的技术:使对象可以通过网路和不同的平台交互。Java IDL可以让对象在不同的语言中交互,如:C, C++, COBOL...

Java IDL实现这一功能通过公共对象请求代理体系结构(CORBA)—一种分布式对象模型行业标准。CORBA的关键特征是IDL(一种无依赖接口定义语言)。每种语言都自己实现了IDL来支持CORBA。Java的语法映射详见Java IDL: Mapping IDL to Java

Java IDL提供了ORB(对象请求代理)来支持分散的程序中的对象之间的交互。ORB是一个类库,实现了Java IDL应用和其它支持CORBA应用之间的底层通信。

这篇教程讲述使用Java IDL构建CORBA分布式应用所需的基本技能。你将实现一个经典的“Hello World”分布式应用。

每两个分布式对象的关系中间有两个部分:客服端和服务端。服务端提供远程接口,客户端去调用这个远程接口。这是包括Java Remote Method Invocation(RMI,RMI-IIOP)和CORBA等大多数分布式对象标准中比较常见的方式。

下图表示了在实现“Hello World”中,一个方法的分布式对象是怎么样在CORBA客户端和服务端怎样被共享的。

Java IDL入门_第1张图片
分布式对象在客户端和服务端被共享

在客户端,应用有一个远程对象的参照(reference)。这个Object Reference有个能被远程调用的存根(stub)方法的替身。存根实际是连接ORB的,所以调用它就是会使ORB的连接服务端发起调用。

在服务端,ORB使用skeleton code翻译处理远程调用命令后调用本地对象。skeleton翻译调用和参数成可以调用的格式然后开始调用方法。当调用返回,skeleton会把报错或结果打包翻译并通过ORB送回给客户端。

在两个ORB之间,通信由多个共享的协议,IIOP(the internet inter-ORB Portocaol)处理。IIOP是基于TCP/IP协议标准的一种标准来定义CORBA风格的ORB之间怎样输送和接收信息的。例如CORBA和IDL,IIOP标准被定义成OMG(the Object Management Group)。

Java IDL开发过程和Hello World教程

1. 定义远程接口
使用OMG的IDL定义你的远程对象的接口。不用Java而用IDL的原因是idlj编译器自动从IDL中 生成Java的stub和skeleton源文件,以及连接ORB的基础代码。同时,你能让他人实现客户端和服务端在别的CORBA风格语言中。

注意,如果你要实现一个已经存在的CORBA服务的客户端或者已经存在的客户端的服务端,你需要从实现者那取得IDL接口。然后用idlj编译器编译这些接口和余下的步骤

//Hello.idl
module HellpApp
{
  interface Hello
  {
    string sayHello();
    oneway void shutdown();
  };
};

2. 编译远程接口
当你用idlj编译后,会生成Java接口文件和stubs和skeletons能让你的应用连接入ORB。

idlj编译器默认只生成客户端的绑定。如果你需要绑定客户端和服务端的skeletons,你得在运行idlj编译时使用 -fall 选项,更多idlj选项(Solaris, Linux, or Mac OS X or Windows)

$idlj -fall Hello.idl
Java IDL入门_第2张图片
编译完成生成上述工程文件

3. 实现服务端
完成编译后,你能用skeletons把服务端应用结合。除了实现远程接口的方法之外,你的服务端代码包括了ORB启动和等待客户端调用的机制。

// HelloServer.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;

import java.util.Properties;

class HelloImpl extends HelloPOA {
  private ORB orb;

  public void setORB(ORB orb_val) {
    orb = orb_val; 
  }
    
  // implement sayHello() method
  public String sayHello() {
    return "\nHello world !!\n";
  }
    
  // implement shutdown() method
  public void shutdown() {
    orb.shutdown(false);
  }
}


public class HelloServer {

  public static void main(String args[]) {
    try{
      // create and initialize the ORB
      ORB orb = ORB.init(args, null);

      // get reference to rootpoa and activate the POAManager
      POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
      rootpoa.the_POAManager().activate();

      // create servant and register it with the ORB
      HelloImpl helloImpl = new HelloImpl();
      helloImpl.setORB(orb); 

      // get object reference from the servant
      org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
      Hello href = HelloHelper.narrow(ref);
          
      // get the root naming context
      org.omg.CORBA.Object objRef =
          orb.resolve_initial_references("NameService");
      // Use NamingContextExt which is part of the Interoperable
      // Naming Service (INS) specification.
      NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

      // bind the Object Reference in Naming
      String name = "Hello";
      NameComponent path[] = ncRef.to_name( name );
      ncRef.rebind(path, href);

      System.out.println("HelloServer ready and waiting ...");

      // wait for invocations from clients
      orb.run();
    } 
        
      catch (Exception e) {
        System.err.println("ERROR: " + e);
        e.printStackTrace(System.out);
      }
          
      System.out.println("HelloServer Exiting ...");
        
  }
}
// 编译.java
$javac HelloServer.java HelloApp/*.java

4. 实现客户端
同样,利用idlj编译生成的stubs完成你的代码。

//HelloClient.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;

public class HelloClient
{
  static Hello helloImpl;

  public static void main(String args[])
    {
      try{
        // create and initialize the ORB
        ORB orb = ORB.init(args, null);

        // get the root naming context
        org.omg.CORBA.Object objRef = 
            orb.resolve_initial_references("NameService");
        // Use NamingContextExt instead of NamingContext. This is 
        // part of the Interoperable naming Service.  
        NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
 
        // resolve the Object Reference in Naming
        String name = "Hello";
        helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));

        System.out.println("Obtained a handle on server object: " + helloImpl);
        System.out.println(helloImpl.sayHello());
        helloImpl.shutdown();

        } catch (Exception e) {
          System.out.println("ERROR : " + e) ;
          e.printStackTrace(System.out);
          }
    }

}
// 编译
$javac HelloClient.java HelloApp/*.java

5. 启动你的应用
启动你的服务后,启动服务端和客户端。

// start orbd
// in Solaris, Linux, or Mac OS X command shell
$orbd -ORBInitialPort 1050 -ORBInitialHost localhost&

// MS-DOS system prompt (Windows)
$start orbd -ORBInitialPort 1050 -ORBInitialHost localhost
// start the hello server
// shell
$java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost&

// MS-DOS
$start java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost
// run the client application
java HelloClient -ORBInitialPort 1050 -ORBInitialHost localhost

你可能感兴趣的:(Java IDL入门)