简述CORBA开发步骤_发散思维的简单例子

简述CORBA开发步骤_发散思维的简单例子因为对CORBA分析的需要,这里写一个简单的CORBA例子。从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题。这个例子实现一个简单的加减乘除的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

因为对CORBA分析的需要,这里写一个简单的CORBA例子。从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题。这个例子实现一个简单的加减乘除的功能的计算器,客户端将参数和请求的方法名传送到服务端,服务端处理这个请求并将结果返回给客户端。

我们知道不同编程语言中的类型的表达,内存模型是不一样的,为此CORBA发明了一套中间描述语言IDL,不同语言平台的ORB实现负责将IDL中的类型映射到本地类型中。因此IDL是我们编写CORBA程序的出发点,首先,我们用IDL来描述我们的接口/对象:

 1 module com{
 2     module bes{
 3         module corba{
 4             module test{
 5                 interface Calc{
 6                     void add(in long a,in long b,out long c);
 7                     void sub(in long a,in long b,out long c);
 8                     void multi(in long a,in long b,out long c);
 9                     void div(in long a,in long b,out long c);
11                 };
12             };
13         };
14     };
15 };

当然接口Calc中的方法的返回值不一定为void,这里将返回值放到了out类型的参数c中,方法可以带有多个out类型的参数。然后我们用idlj工具(jdk自带)将Calc.idl转换为对应java的描述,并生成Stub和POA等类:

简述CORBA开发步骤_发散思维的简单例子

idlj给我们生成很多文件,首先我们来看一下UML图:

简述CORBA开发步骤_发散思维的简单例子

上面的图不涉及工具类CalcHelper和CalcHolder,这两个类的作用在后而阐述。

package com.bes.corba.test; /** * com/bes/corba/test/_CalcStub.java . * 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成 * 从Hello.idl * 2016年2月15日 星期一 下午09时08分34秒 CST */ public class _CalcStub extends org.omg.CORBA.portable.ObjectImpl implements com.bes.corba.test.Calc { public void add (int a, int b, org.omg.CORBA.IntHolder c) { org.omg.CORBA.portable.InputStream $in = null; try { org.omg.CORBA.portable.OutputStream $out = _request ("add", true); $out.write_long (a); $out.write_long (b); $in = _invoke ($out); c.value = $in.read_long (); return; } catch (org.omg.CORBA.portable.ApplicationException $ex) { $in = $ex.getInputStream (); String _id = $ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException $rm) { add (a, b, c ); } finally { _releaseReply ($in); } } // add public void sub (int a, int b, org.omg.CORBA.IntHolder c) { org.omg.CORBA.portable.InputStream $in = null; try { org.omg.CORBA.portable.OutputStream $out = _request ("sub", true); $out.write_long (a); $out.write_long (b); $in = _invoke ($out); c.value = $in.read_long (); return; } catch (org.omg.CORBA.portable.ApplicationException $ex) { $in = $ex.getInputStream (); String _id = $ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException $rm) { sub (a, b, c ); } finally { _releaseReply ($in); } } // sub public void multi (int a, int b, org.omg.CORBA.IntHolder c) { org.omg.CORBA.portable.InputStream $in = null; try { org.omg.CORBA.portable.OutputStream $out = _request ("multi", true); $out.write_long (a); $out.write_long (b); $in = _invoke ($out); c.value = $in.read_long (); return; } catch (org.omg.CORBA.portable.ApplicationException $ex) { $in = $ex.getInputStream (); String _id = $ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException $rm) { multi (a, b, c ); } finally { _releaseReply ($in); } } // multi public void div (int a, int b, org.omg.CORBA.IntHolder c) { org.omg.CORBA.portable.InputStream $in = null; try { org.omg.CORBA.portable.OutputStream $out = _request ("div", true); $out.write_long (a); $out.write_long (b); $in = _invoke ($out); c.value = $in.read_long (); return; } catch (org.omg.CORBA.portable.ApplicationException $ex) { $in = $ex.getInputStream (); String _id = $ex.getId (); throw new org.omg.CORBA.MARSHAL (_id); } catch (org.omg.CORBA.portable.RemarshalException $rm) { div (a, b, c ); } finally { _releaseReply ($in); } } // div // Type-specific CORBA::Object operations private static String[] __ids = { "IDL:com/bes/corba/test/Calc:1.0"}; public String[] _ids () { return (String[])__ids.clone (); } private void readObject (java.io.ObjectInputStream s) throws java.io.IOException { String str = s.readUTF (); String[] args = null; java.util.Properties props = null; org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props); try { org.omg.CORBA.Object obj = orb.string_to_object (str); org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate (); _set_delegate (delegate); } finally { orb.destroy() ; } } private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException { String[] args = null; java.util.Properties props = null; org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props); try { String str = orb.object_to_string (this); s.writeUTF (str); } finally { orb.destroy() ; } } } // class _CalcStub

_CalcStub是存根类,有过远程调用编程经验的读者应该对这个词比较熟悉,它是远程对象在本地的一个代理(Proxy)。从业务划分角度来说,CORBA这些底层的东西不应该太多地污染到我们的应用,比如这个_CalcStub是我们不希望在业务代码中出现的,我们只需要看到我们需要的Calc。客户端从ORB中拿到的Calc接口实现其实是一个_CalcStub,客户程序对Calc接口中的方法进行调用时,_CalcStub将相应方法的调用转发到服务端,然后将服务器的响应返回给客户端,从而成功从欺骗客户端程序。

_CalcStub继承了ObjectImpl类,这使得_CalcStub能够关联到ORB环境中,从而完成远程调用。

idlj工具并没有直接在Calc.java中定义idlj方法的java语言描述,而是在CalcOperation.java中。Calc接口继承了IDLEntity,org.omg.CORBA.Object和CalcOperation三个接口:

IDLEntity是一个标记接口,表明Calc接口是一种IDL接口,这个与org.omg.CORBA.Object有点相类似,但实现了org.omg.CORBA.Object接口的对象不一定是IDL描述的,因此这里单独把IDLEntity拎出来。

org.omg.CORBA.Object接口定义了一些CORBA相关的方法,因为客户端所使用的是Calc,参数传递到ORB中语义上也是 Calc类型,当然我们不能将非IDL的对象传递到ORB中,ORB无法完成那样子的操作;Calc接口继承 org.omg.CORBA.Object(ORB层面使用的是org.omg.CORBA.Object),那就意味了通过编译器来保证类型安全(避免 强制转换,ClassCastException之类的异常)。

package com.bes.corba.test; /** * com/bes/corba/test/CalcOperations.java . * 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成 * 从Hello.idl * 2016年2月15日 星期一 下午09时08分34秒 CST */ public interface CalcOperations { void add (int a, int b, org.omg.CORBA.IntHolder c); void sub (int a, int b, org.omg.CORBA.IntHolder c); void multi (int a, int b, org.omg.CORBA.IntHolder c); void div (int a, int b, org.omg.CORBA.IntHolder c); } // interface CalcOperations

CalcOperation是相对应的IDL映射。

package com.bes.corba.test; /** * com/bes/corba/test/CalcPOA.java . * 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成 * 从Hello.idl * 2016年2月15日 星期一 下午09时08分34秒 CST */ public abstract class CalcPOA extends org.omg.PortableServer.Servant implements com.bes.corba.test.CalcOperations, org.omg.CORBA.portable.InvokeHandler { // Constructors private static java.util.Hashtable _methods = new java.util.Hashtable (); static { _methods.put ("add", new java.lang.Integer (0)); _methods.put ("sub", new java.lang.Integer (1)); _methods.put ("multi", new java.lang.Integer (2)); _methods.put ("div", new java.lang.Integer (3)); } public org.omg.CORBA.portable.OutputStream _invoke (String $method, org.omg.CORBA.portable.InputStream in, org.omg.CORBA.portable.ResponseHandler $rh) { org.omg.CORBA.portable.OutputStream out = null; java.lang.Integer __method = (java.lang.Integer)_methods.get ($method); if (__method == null) throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); switch (__method.intValue ()) { case 0: // com/bes/corba/test/Calc/add  { int a = in.read_long (); int b = in.read_long (); org.omg.CORBA.IntHolder c = new org.omg.CORBA.IntHolder (); this.add (a, b, c); out = $rh.createReply(); out.write_long (c.value); break; } case 1: // com/bes/corba/test/Calc/sub  { int a = in.read_long (); int b = in.read_long (); org.omg.CORBA.IntHolder c = new org.omg.CORBA.IntHolder (); this.sub (a, b, c); out = $rh.createReply(); out.write_long (c.value); break; } case 2: // com/bes/corba/test/Calc/multi  { int a = in.read_long (); int b = in.read_long (); org.omg.CORBA.IntHolder c = new org.omg.CORBA.IntHolder (); this.multi (a, b, c); out = $rh.createReply(); out.write_long (c.value); break; } case 3: // com/bes/corba/test/Calc/div  { int a = in.read_long (); int b = in.read_long (); org.omg.CORBA.IntHolder c = new org.omg.CORBA.IntHolder (); this.div (a, b, c); out = $rh.createReply(); out.write_long (c.value); break; } default: throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE); } return out; } // _invoke // Type-specific CORBA::Object operations private static String[] __ids = { "IDL:com/bes/corba/test/Calc:1.0"}; public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId) { return (String[])__ids.clone (); } public Calc _this() { return CalcHelper.narrow( super._this_object()); } public Calc _this(org.omg.CORBA.ORB orb) { return CalcHelper.narrow( super._this_object(orb)); } } // class CalcPOA

CalcPOA:它工作在服务端,POA是Portable Object Adapter的缩写,这里Adapter(适配器)的语义是指适配相应的编程语言中的对象(比如在java中那意思就是指 Java对象的适配器),适配器的作用有三点:

1:接受客户端发过来的调用请求,反序列化(Unmarshalling)参数,方法名等,然后将请求分发给对应的Servant。POA和Servant之间的关系如下图。

2:将对象引用(Object Reference)和相应的Servant起来(可以看到Servant._object_id方法),比如我们在EJB中的有状态会话Bean。

3:负责Servant的生命周期管理(如创建,钝化,销毁等),这里又让我联想到了EJB的生命周期。到这里这里我们可以清楚Home接口存在的理由。

简述CORBA开发步骤_发散思维的简单例子

好吧,我们要实现的例子确实很简单,在这个例子中,读者只需要了解到第一点即可(CORBA水很深,很容易死里面去的)。idlj为我们生成的POA中,集Servant,CalcOperation和InvocationHandler于一身,有越殂代疱的嫌疑,当然这并不影响程序的正常执行,当然如果服务端比较关注2,3两点的话,自己实现POA还是很有必要的,但这已经超出了本文的范围。

同样地ORB的东西不应该玷污到我们服务端的业务逻辑 ,Servant和InvocationHandler将POA关联到ORB中去。注意Servant和InvocationHandler是两接口是分开的,这一点还不是太清楚(也许是为了特性的划分吧)。

 

package com.bes.corba.test; /** * com/bes/corba/test/CalcHelper.java . * 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成 * 从Hello.idl * 2016年2月15日 星期一 下午09时08分34秒 CST */ abstract public class CalcHelper { private static String _id = "IDL:com/bes/corba/test/Calc:1.0"; public static void insert (org.omg.CORBA.Any a, com.bes.corba.test.Calc that) { org.omg.CORBA.portable.OutputStream out = a.create_output_stream (); a.type (type ()); write (out, that); a.read_value (out.create_input_stream (), type ()); } public static com.bes.corba.test.Calc extract (org.omg.CORBA.Any a) { return read (a.create_input_stream ()); } private static org.omg.CORBA.TypeCode __typeCode = null; synchronized public static org.omg.CORBA.TypeCode type () { if (__typeCode == null) { __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc (com.bes.corba.test.CalcHelper.id (), "Calc"); } return __typeCode; } public static String id () { return _id; } public static com.bes.corba.test.Calc read (org.omg.CORBA.portable.InputStream istream) { return narrow (istream.read_Object (_CalcStub.class)); } public static void write (org.omg.CORBA.portable.OutputStream ostream, com.bes.corba.test.Calc value) { ostream.write_Object ((org.omg.CORBA.Object) value); } public static com.bes.corba.test.Calc narrow (org.omg.CORBA.Object obj) { if (obj == null) return null; else if (obj instanceof com.bes.corba.test.Calc) return (com.bes.corba.test.Calc)obj; else if (!obj._is_a (id ())) throw new org.omg.CORBA.BAD_PARAM (); else { org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate (); com.bes.corba.test._CalcStub stub = new com.bes.corba.test._CalcStub (); stub._set_delegate(delegate); return stub; } } public static com.bes.corba.test.Calc unchecked_narrow (org.omg.CORBA.Object obj) { if (obj == null) return null; else if (obj instanceof com.bes.corba.test.Calc) return (com.bes.corba.test.Calc)obj; else { org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate (); com.bes.corba.test._CalcStub stub = new com.bes.corba.test._CalcStub (); stub._set_delegate(delegate); return stub; } } }

CalcHelper:从名字上可以看出,它是一个工具类,它的职责在有:

1、通过提供narrow方法和RepositoryId等信息来实现类型安全。

2、与Any类型之间的进行转换。

3、从InputStream中读出Calc(对象引用),将Calc写出到OutputStream中。

我们的例子中将只用到第一点。

 

package com.bes.corba.test; /** * com/bes/corba/test/CalcHolder.java . * 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成 * 从Hello.idl * 2016年2月15日 星期一 下午09时08分34秒 CST */ public final class CalcHolder implements org.omg.CORBA.portable.Streamable { public com.bes.corba.test.Calc value = null; public CalcHolder () { } public CalcHolder (com.bes.corba.test.Calc initialValue) { value = initialValue; } public void _read (org.omg.CORBA.portable.InputStream i) { value = com.bes.corba.test.CalcHelper.read (i); } public void _write (org.omg.CORBA.portable.OutputStream o) { com.bes.corba.test.CalcHelper.write (o, value); } public org.omg.CORBA.TypeCode _type () { return com.bes.corba.test.CalcHelper.type (); } }

CalcHolder:这个类在Calc被作为out或者inout类型的参数传递时候被使用,如果我们在另一个IDL方法中使用Calc作为参数,那么生成的代码将会是这样子的:

void test(int a, int b, CalcHolder calc) 

CalcHolder负责从InputStream或者OuputStream分别读出和写入Calc,从CalcHolder生成的代码中我们可以看出,CalcHolder的_read和_write方法将相应的操作委托给了CalcHelper。

哆嗦了这么多,是时候拿出我们的客户端和服务端了。

服务端代码:

CalculatorImpl是Servant的实现,它继承了CalcPOA类。

package com.bes.corba.impl; import org.omg.CORBA.IntHolder; import com.bes.corba.test.CalcPOA; public class CalculatorImpl extends CalcPOA{ @Override public void add(int a, int b, IntHolder c) { c.value=a+b; } @Override public void sub(int a, int b, IntHolder c) { c.value=a-b; } @Override public void multi(int a, int b, IntHolder c) { c.value=a*b; } @Override public void div(int a, int b, IntHolder c) { c.value=a/b; } }

Server类:

package com.bes.corba.test; 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 com.bes.corba.test.Calc; import com.bes.corba.test.CalcHelper; import com.bes.corba.impl.CalculatorImpl; public class Server { public static void main(String[] args) throws Exception{ /* * ORB 初始化。 */ ORB orb=ORB.init(args,null); /* * 获取根POA并初始化。 */ POA rootPoa=POAHelper.narrow(orb.resolve_initial_references("RootPOA") ); rootPoa.the_POAManager().activate(); /* * 构建一个CalculatorImpl。 */ CalculatorImpl calculatorImpl=new CalculatorImpl(); /* * 将Servant注册到RootPOA中,建立Servant到Object Reference的相互映射, * 注意这里具体行为跟RootPOA的POA Policy有关。 */ org.omg.CORBA.Object ref=rootPoa.servant_to_reference(calculatorImpl); Calc iref=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,iref); System.out.println("Calculator server ready..."); /* * 阻塞直到ORB关闭。 */ orb.run(); } }

客户端代码Client

package com.bes.corba.test; import org.omg.CORBA.IntHolder; import org.omg.CORBA.ORB; import org.omg.CosNaming.NamingContextExt; import org.omg.CosNaming.NamingContextExtHelper; import com.bes.corba.test.Calc; import com.bes.corba.test.CalcHelper; public class Client { public static void main(String[] args) throws Exception{ /* * 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"; Calc calc=CalcHelper.narrow(ncRef.resolve_str(name)); /* * 调用对象的方法。 */ IntHolder result=new IntHolder(); calc.add(1,2,result); System.out.printf("1+2=%d\n",result.value); } }

启动命名服务,命名服务器不一定运行在对象服务器的进程中,尤其是在一个分布式的环境中,命名服务器与对象服务器通常是一对多的关系。

orbd -ORBInitialPort 1050 -ORBInitialHost localhost& 

简述CORBA开发步骤_发散思维的简单例子

 启动服务端:

java HelloServer -ORBInitialPort 1050 -ORBInitialHost localhost 

ORBInitialPort和ORBInitialHost参数指定了命名服务器的主机名和端口号。

简述CORBA开发步骤_发散思维的简单例子

启动客户端:

java com.bes.corba.test.Client -ORBInitialPort 1050 -ORBInitialHost localhost 

 简述CORBA开发步骤_发散思维的简单例子

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/167935.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • u盘越狱卡代码怎么办_使用爱思助手制作越狱U盘教程

    u盘越狱卡代码怎么办_使用爱思助手制作越狱U盘教程U盘越狱iPhone绕ID最新教程及各种坑解决,吐血之作(超详细超简单教程)-balenaEtcher-Checkm8-bootra1n这是安装多个苹果版本及虚拟机版本后成功的教程,由于资源上传到百度云盘下载只有几十KB,所以为了大家能够尽快的体验上苹果系统,文章中涉及的所有工具请大家加QQ群进行交流下载:1064543120一、工具下载准备一台Windows系统电脑准备一个>2G存储U盘下载群文件中balenaEtcher、Checkm8.info_iCloudBypass、bootr

  • Html 表格

    Html 表格

  • Linux系统的内核态和用户态[通俗易懂]

    Linux系统的内核态和用户态[通俗易懂]一、 Unix/Linux的体系架构  如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供

  • c++中无法打开源文件_无法打开源文件iostream

    c++中无法打开源文件_无法打开源文件iostream一、无法打开文件“xxx.lib”出现这种错误一般为①未添加xxx.lib库文件②库添加后,路径不对,找不到对应的库文件路径解决方案:先查看库文件是否已经添加若未添加,右击项目->属性->链接器->输入;将库文件加入即可如果库文件已经添加,仍然报错,此时需要查看生成的库文件的路径了。先找到生成库文件的路径,右击项目->属性->常规->查看输出目录是否与生成的库文件的路径是否匹配,若不匹配,修改路径即可。二、无法打开源文件说明是库的附加包含路径有问题

    2022年10月14日
  • 几种常见模式识别算法整理和总结

    几种常见模式识别算法整理和总结

    2021年11月29日
  • Java之多线程断点下载的实现

    Java之多线程断点下载的实现

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号