基于Java的CORBA技术复杂应用范例
 
本文是继Hello World例程的又一个复杂应用范例,目的是看看真正的基于Java的CORBA技术应用是什么样子。
 
本文通过一个四则运算实例来展示一个基于Java的CORBA应用,范例如下:
 
一、定义IDL
 
module zzvcom{
            module cbrtest{
                interface Calc{
                        void add(in long a,in long b,out long c);
                        void sub(in long a,in long b,out long c);
                        void muti(in long a,in long b,out long c);
                        void div(in long a,in long b,out long c);
                };
        };
};
 
二、根据IDL生成存根和代理等代码
 
idlj -fall Hello.idl
 
三、开发CORBA服务
 
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import zzvcom.cbrtest.Calc;
import zzvcom.cbrtest.CalcHelper;
import zzvcom.cbrtest.CalcPOA;

/**
* 四则运算的服务端实现
*
* @author leizhimin 2009-12-17 9:54:43
*/

class CalcImpl extends CalcPOA {
        private ORB orb;

        public void setORB(ORB orb_val) {
                orb = orb_val;
        }

        public void add(int a, int b, IntHolder c) {
                c.value = a + b;
        }

        public void sub(int a, int b, IntHolder c) {
                c.value = a - b;
        }

        public void muti(int a, int b, IntHolder c) {
                c = new IntHolder(a * b);
        }

        public void div(int a, int b, IntHolder c) {
                c = new IntHolder(a / b);
        }

        public void shutdown() {
                orb.shutdown(false);
        }
}

public class CalcServer {

        public static void main(String args[]) {
                try {
                        //创建一个ORB实例
                        ORB orb = ORB.init(args, null);

                        //得到一个RootPOA的引用,并激活POAManager
                        POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
                        rootpoa.the_POAManager().activate();

                        //创建一个CalcImpl实例(servant),并注册到ORB上
                        CalcImpl calcImpl = new CalcImpl();
                        calcImpl.setORB(orb);

                        //从服务中得到对象的引用
                        org.omg.CORBA.Object ref = rootpoa.servant_to_reference(calcImpl);
                        Calc href = CalcHelper.narrow(ref);

                        //得到一个根名称的上下文
                        org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
                        NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

                        //在命名上下文中绑定这个对象
                        String name = "Calc";
                        NameComponent path[] = ncRef.to_name(name);
                        ncRef.rebind(path, href);

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

                        //启动线程服务,等待客户端的调用
                        orb.run();
                } catch (Exception e) {
                        System.err.println("ERROR: " + e);
                        e.printStackTrace(System.out);
                }
                System.out.println("CalcServer Exiting ...");
        }
}
 
四、开发客户端
 
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import zzvcom.cbrtest.Calc;
import zzvcom.cbrtest.CalcHelper;

/**
* 四则运算的客户端调用
*
* @author leizhimin 2009-12-17 10:35:32
*/

public class CalcClient {
        static Calc calcImpl;

        public static void main(String args[]) {
                try {
                        //创建一个ORB实例
                        ORB orb = ORB.init(args, null);

                        //获取根名称上下文
                        org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
                        NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

                        //从命名上下文中获取接口实现对象
                        String name = "Calc";
                        calcImpl = CalcHelper.narrow(ncRef.resolve_str(name));

                        //调用接口对象的方法
                        System.out.println("Obtained a handle on server object: " + calcImpl);
                        System.out.println();
                        IntHolder add_val = new IntHolder();
                        calcImpl.add(1, 2, add_val);
                        System.out.println(add_val.value);
                } catch (Exception e) {
                        System.out.println("ERROR : " + e);
                        e.printStackTrace(System.out);
                }
        }
}
 
五、启动CORBA服务器
 
先编译所有的Java文件:javac -Xlint:unchecked -d . *.java
 
编译后就可以调用了。
 
 
六、开启CORBA服务
 
 
七、启动CORBA客户端
 
 
可以看到当调用add(1,2)方法的时候,通过CORBA服务调用,从服务端获得了计算结果3.
 
这个例子与HelloWorld的例子不同在于:
 
1、如何组织接口的java包。
2、如何定义带参数,和返回值的方法。
3、如何调用带参数和返回值的方法。
 
理解了本例,就可以做更复杂的Java应用了。