分享
 
 
 

RMI、CORBA、IIOP简单实例--2. CORBA

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

CORBA基本介绍

CORBA(公用对象请求代理体系)是OMG(对象管理组织)于1991年提出的基于对象技术的分布计算应用软件体系结构。CORBA标准主要分为三个部分:接口定义语言(IDL)、对象请求代理(ORB),以及ORB之间的互操作协议IIOP,核心是对象请求代理。CORBA可以抽象系统平台、网络通讯及编程语言的差异。通过在CORBA技术规范中定义多种类型的服务,如名字服务(Naming Service)、事务服务(Transaction Service)、对象生命期服务(LifeCycle Service)、并发控制服务(Concurrency Control Service)、时间服务(Time Service)等功能,为应用软件开发者提供一个全面、健壮、可扩展的分布对象计算平台,使面向对象的应用软件在分布异构环境下方便地实现可重用、易移植和互操作。

与RMI比较

与RMI 不同,CORBA 不属于Java 平台本身。OMG(Object Management Group,对象管理组织)发明了CORBA 规范,CORBA 被设计成与平台和语言无关。因此,CORBA对象可以运行于任何平台之上,位于网络的任何位置,还可以用任何语言(包括 Java、C、C++和Smalltalk 等)编写,只要该语言具有IDL(Interface Definition Language,接口定义语言)的映射。

与RMI 相比,CORBA 是为更大、可伸缩更强的系统准备的,在这些系统中可能有数千个对象;CORBA 的编程和部署比RMI 更复杂,但允程序员开发需要事务、安全性等支持的企业级系统;CORBA 的命名服务也比RMI 命名注册功能更强大和灵活。

CORBA 的实现称为ORB(Object Request Broker,对象请求代理)。Java IDL 即是CORBA 的一个实现,它是JDK1.3 或更高版本的核心软件包之一,定义在org.omg.CORBA及其子包中。在Java IDL 的支持下,开发人员可以使用如下两种方法将Java 和CORBA 集成在一起:

·??创建Java 对象并使之可在CORBA ORB 中展开,

·??创建Java 类并作为和其它ORB 一起展开的CORBA 对象的客户。这种方法提供了另外一种途径,通过它Java 可以被用于将你的新的应用和以前遗留的系统相集。

采用Java创建CORBA应用

CORBA对象服务的实现方式分为两种:对象的命名引用方式和字符串化对象引用方式。不论采用何种高级语言,创建CORBA应用程序的过程大体如下:

● 编写IDL接口定义文件;

● 将接口定义文件编译为相应高级语言源代码,产生服务器框架与客户端存根;

● 基于服务器框架,编写服务对象实现程序;

● 基于客户端存根,编写客户对象调用程序;

● 分别编译客户对象和服务对象程序;

● 运行服务对象和客户对象程序;

CORBA实例分析

下面通过一个实例,描述如何通过Java创建CORBA应用程序。

1. 接口定义 (Hello.idl)

Hello.idl

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);

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有