module HelloApp
{
interface Hello
{
string sayHello(in string message);
};
};
通过Sun提供的将IDL文件编译成Java源代码的工具idlj(jdk1.3.0_01以上版本),为接口定义文件生成客户端存根和服务器框架。具体操作如下:
idlj -oldImplBase -fall Hello.idl
编译后将在 HelloApp 子目录中形成以下六个文件:
n _HelloImplBase.java
该抽象类是一个服务器 skeleton,它可为服务器提供基本的 CORBA 功能。它实现 Hello.java 接口。服务器类 HelloServant 扩展 _HelloImplBase。
n _HelloStub.java
该类是客户机 stub,可为客户机提供 CORBA 功能。它实现 Hello.java 接口。
n Hello.java
该接口含有 IDL 接口的 Java 版本。Hello.java 接口扩展 org.omg.CORBA.Object 并提供标准的 CORBA 对象功能。
n HelloHelper.java
这是一个终态类,可以提供辅助功能,特别是提供将 CORBA 对象引用转换为适当类型所需的 narrow() 方法。
n HelloHolder.java
这是一个终态类,其中含有 Hello 类型的公有实例成员。它可为“out” 和 “inout” 变量提供操作。CORBA 有这些变量,但不容易映射为 Java 的语义。
n HelloOperations.java
这是一个接口类,其中含有方法 sayHello()。
要完成该应用程序,只需在文件 HelloServer.java 和 HelloClient.java 中提供服务器和客户机的实现即可。
2. 接口实现
HelloImpl.java是Hello IDL 接口的实现;每个Hello实例都由一个HelloImpl实例来实现。HelloImpl是_HelloImplBase的子类,_HelloImplBase是由 idlj编译器从示例 IDL 中生成的。
HelloImpl.java
/*
* @author javamxj (CSDN Blog) 创建日期 2004-12-27
*/
import HelloApp.*;
public class HelloImpl extends _HelloImplBase {
/* 构造函数 */
public HelloImpl() {
super();
}
/* 实现接口声明方法sayHello */
public String sayHello(String message) {
System.out.println("我在CORBA的服务器端,客户端正在调用'sayHello'方法。 ");
System.out.println("Hello " + message);
return message;
}
}
3. 服务器
服务器类含有服务器的main()方法,可完成以下任务:
· 创建一个 ORB 实例
· 创建一个HelloImpl实例(CORBA Hello对象的实现)并通知 ORB
· 获取一个命名上下文的 CORBA 对象引用,在该命名上下文中注册新 CORBA 对象
· 在命名上下文中将新对象注册在“Hello”名下
· 等待对新对象的调用
HelloSever.java
/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import org.omg.CosNaming.*; import org.omg.CORBA.*; public class HelloServer { public static void main(String args[]) { try { /* 创建和初始化 ORB */ ORB orb = ORB.init(args, null); System.out.println("开始 ORB Server ..."); /* 创建一个实例并将其向 ORB 注册 */ HelloImpl helloImpl = new HelloImpl(); orb.connect(helloImpl); System.out.println("将实例注册到ORB "); /* 获取根命名上下文 */ org.omg.CORBA.Object objRef =orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); /* 绑定命名中的对象引用 */ NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = { nc }; ncRef.rebind(path, helloImpl); /* 等待来自客户机的调用 */ java.lang.Object sync = new java.lang.Object(); synchronized (sync) { sync.wait(); } System.out.println("等待CORBA客户端调用..."); } catch (Exception e) { System.err.println("错误: " + e); e.printStackTrace(System.out); } } } 4. 客户端 下面的应用程序客户机将完成以下任务: · 创建一个 ORB · 获取一个指向命名上下文的引用 · 在命名上下文中查找 "Hello" 并获得指向该 CORBA 对象的引用 · 调用对象的 sayHello() 操作并打印结果 HelloClient.java
/*
* @author javamxj (CSDN Blog) 创建日期 2004-12-27
*/
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class HelloClient {
public static void main(String args[]) {
try {
/* 创建和初始化 ORB */
ORB orb = ORB.init(args, null);
/* 获取根命名上下文 */
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
/* 解析命名中的对象引用 */
NameComponent nc = new NameComponent("Hello", "");
NameComponent path[] = { nc };
Hello h = HelloHelper.narrow(ncRef.resolve(path));
/* 调用 Hello 服务器对象并打印结果 */
System.out.println("我在客户端,开始调用CORBA服务器端的'sayHello'方法");
System.out.println("欢迎, " + h.sayHello("javamxj blog"));
} catch (Exception e) {
System.out.println("错误 : " + e);
e.printStackTrace(System.out);
}
}
}
CORBA Server/Client的编译与运行
· 把上面4个文件复制到D:\CorbaSample目录下,在此目录下建立Client和Server目录,假设它们分别为客户端和服务端。
· 编译Hello.idl
D:\CorbaSample>idlj -oldImplBase -fall Hello.idl
这会生成一个HelloApp的目录
· 编译所有java文件:
D:\CorbaSample>javac *.java HelloApp/*.java
· 分别在Client和Server目录下建立HelloApp子目录,将D:\CorbaSample\HelloApp目录中的
_HelloStub.class
Hello.class
HelloHelper.class
HelloHolder.class
HelloOperations.class
复制到D:\CorbaSample\Client\HelloApp目录下,再将D:\CorbaSample目录中的HelloClient.class复制到D:\CorbaSample\Client目录下。
将D:\CorbaSample\HelloApp目录中的
_HelloImplBase.class
Hello.class
HelloOperations.class
复制到D:\CorbaSample\Server\HelloApp目录下, 再将D:\CorbaSample目录中的HelloServer.class和 HelloImpl.class 复制到D:\CorbaSample\Server目录中
(注意:当然,你可以不必建立Server和Client目录及以上复制文件的操作,可以直接在D:\CorbaSample目录中进行操作,我这样做的目的主要是为了区分客户端和服务端)
· 确保名字服务器处于运行状态:
D:\CorbaSample\Server>tnameserv -ORBInitialPort 1050
· 启动 Hello 服务器:
D:\CorbaSample\Server>java HelloServer -ORBInitialPort 1050
· CORBA客户端调用CORBA服务:
D:\CorbaSample\Client>java HelloClient -ORBInitialPort 1050
(本地调用,不需要用-ORBInitialHost参数来指定远程的IP地址)
D:\CorbaSample\Server>java HelloClient -ORBInitialHost localhost -ORBInitialPort 1050
(远程调用CORBA服务,可以将localhost替换成远程的IP地址)
图1. 客户端没有调用CORBA服务之前
图2. 客户端调用CORBA服务之后
一点补充:
不知道大家注意到没有,在JDK1.4编译idl文件时使用的 idlj -oldImplBase -fall Hello.idl
这个命令带有“-oldImplBase”参数,表示这是一个老版本的实现。而JDK1.4版本下,可以直接使用
idlj -fall Hello.idl 命令,这样idlj编译器对服务器端生成的是轻便对象适配器(POA)。
(直接再命令行敲入idlj可以得到其使用说明)
这里我就不作详细说明了,操作基本上与上一个例子相似。
首先在 D:\CorbaSample2 目录下编写下面4个文件,然后依次进行如下操作:
D:\CorbaSample2>idlj -fall Hello.idl
D:\CorbaSample2>javac *.java HelloApp/*.java
D:\CorbaSample2>tnameserv -ORBInitialPort 1050
D:\CorbaSample2>java HelloServer -ORBInitialPort 1050
D:\CorbaSample2>java HelloClient -ORBInitialPort 1050
(注意:这里为了方便.我没有再划分客户端和服务端。进行对比,你可以发现这次idlj编译器生成的文件与上例中生成的文件有和不同。)
Hello.idl
module HelloApp { interface Hello { string sayHello(in string message); }; }; HelloImpl.java
/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import org.omg.CORBA.*; import HelloApp.HelloPOA; public class HelloImpl extends HelloPOA { private ORB orb; public void setORB(ORB orb_val) { orb = orb_val; } /* 实现接口声明方法sayHello */ public String sayHello(String message) { System.out.println("我在CORBA的服务器端,客户端正在调用'sayHello'方法。 "); System.out.println("Hello " + message); return message; } } HelloServer.java
/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import org.omg.PortableServer.POA; public class HelloServer { 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(); /* 创建一个实例并将其向 ORB 注册 */ HelloImpl h = new HelloImpl(); h.setORB(orb); System.out.println("将实例注册到ORB "); /* 获取对服务端的对象引用 */ org.omg.CORBA.Object ref = rootpoa.servant_to_reference(h); Hello href = HelloHelper.narrow(ref); /* 从名称服务中获取根元素名称上下文 */ org.omg.CORBA.Object objRef = orb .resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); /* 在Hello名称下注册新对象 */ String name = "Hello"; NameComponent path[] = ncRef.to_name(name); ncRef.rebind(path, href); /* 等待客户端的调用。 */ orb.run(); System.out.println("等待CORBA客户端调用..."); } catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } System.out.println("HelloServer Exiting ..."); } } HelloClient.java
/* * @author javamxj (CSDN Blog) 创建日期 2004-12-27 */ import HelloApp.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class HelloClient { 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); /* 在名称上下文中查找Hello对象,获取对它的引用。 */ String name = "Hello"; Hello h = HelloHelper.narrow(ncRef.resolve_str(name)); System.out.println("我在客户端,开始调用CORBA服务器端的'sayHello'方法"); System.out.println("欢迎, " + h.sayHello("javamxj blog")); } catch (Exception e) { System.out.println("错误 : " + e); e.printStackTrace(System.out); } } }
本文地址:http://com.8s8s.com/it/it11377.htm