第五章上机报告
一.题目要求 (1)实验题目 题目1.Java版CORBA程序1——HelloWorld 题目2.Java版CORBA程序2——Counter
(2)实验目的 ①掌握组件化开发的概念,了解CORBA模型以及ORB机制 ②掌握CORBA组件编程方法
(3)实验步骤 1.配制环境JDK环境。 2.编写编译IDL接口。 3.编写编译服务端程序。 4.编写编译客户端程序。 5.运行测试与调试。
二.问题分析 2.1 题目分析 本实验需要进行Java的组件化开发方法,利用组件编程的方法来实现题目一 HelloWorld和题目二Counter。 (组件化介绍) 组件化开发的思想其实也就是分而治之(最重要的架构思想),页面逻辑过于复杂,便将页面分为很多个业务组件模块分而治之,这样的话维护人员每次只需要改动对应的模块即可,以达到最大程度的降低开发难度与维护成本的效果,所以现在比较好的框架都会对组件化作一定程度的实现。 组件是对逻辑的封装,不限于图形元素。即我们可以把一个倒计时做成组件、把一段动画做成组件、把路由做成组件、把数据架构做成组件等,而这些并不能称为控件组件具备单个可移植性,即“随加载随用”,不需要为其准备复杂的基础条件(如引入样式、引入框架等),显著减少了应用程序的复杂度,避免了软件资源的浪费。 (组件化与模块化区别) 组件:最初的目的是代码重用,功能相对单一或者独立。在整个系统的代码层次上位于最底层,被其他代码所依赖,所以说组件化是纵向分层。 模块:最初的目的是将同一类型的代码整合在一起,所以模块的功能相对复杂,但都同属于一个业务。不同模块之间也会存在依赖关系,但大部分都是业务性的互相跳转,从地位上来说它们都是平级的。 2.2 组件设计 (1)题目一:HelloWorld
编写IDL接口HelloWorld.idl: module sample{ interface HelloWorld{ string sayHello(); }; }; CORBA 的IDL接口作为服务对象功能的详细描述,封装了服务对象提供服务方法的全部信息,客户对象利用该接口获取服务对象的属性、访问服务对象中的方法。Sample包中定义了一个接口HelloWorld,其中有一个String类型的sayHello()方法,由于要输出姓名和学号信息,所以讲string类型方法改为wstring类型,可以处理多字节的字符串,即可以实现姓名学号的输出。编译IDL接口:D:\CORBA >idlj –fall HelloWorld.idl 编译接口结果将生成sample包,含有以下源文件。 _HelloWorldStub.java HelloWorld.java HelloWorldHelper.java HelloWorldHolder.java HelloWorldOperations.java HelloWorldPOA.java ①_HelloWorldStub.java源文件中_HelloWorldStub类继承了org.omg.CORBA.portable.ObjectImpl。是客户端类,用于接受本地的方法的调用,为客户端提供CORBA 服务功能,实现了HelloWorld.java的接口。 ②HelloWorld.java源文件是IDL接口的java语言实现,是方法sayHello()的实现。 ③HelloWorldHelper.java类提供了辅助的方法,将CORBA对象引用转化成合适的类型。 ④HelloWorldOperations.java是用java语言描述的IDL接口。 ⑤HelloWorldPOA.java是服务端的skeleton类,实现了服务端的接口,为服务端提供CORBA 服务功能。编写并编译服务端程序:HelloWorldServer.java。HelloWorldServer.java服务端程序中引入了要使用的包,声明服务应用类并编写main代码块,main方法中try代码块需要建立ORB对象,同时使用ORB的名字服务寻找Hello对象,等待客户调用。最后定义sayHello服务类,该类向客户端返回“Hello World!1702 jiachenge”。编写并编译客户端程序: HelloWorldClient.java。HelloWorldClient.java客户端程序中引入了要使用的包,并声明客户应用类,编写main方法,在try代码块中建立ORB对象,使用ORB的名字服务寻找Hello对象,调用sayHello操作,把服务端返回的内容显示在屏幕上。(2)题目二:Counter
编写IDL接口counter.idl: module CounterApp{ interface Counter{ readonly attribute long value; void inc(); void dec(); }; }; CORBA 的IDL接口作为服务对象功能的详细描述,封装了服务对象提供服务方法的全部信息,客户对象利用该接口获取服务对象的属性、访问服务对象中的方法。CounterApp包中定义了一个接口Counter,其中定义两个方法,分别为实现加1的inc()方法和实现减1的dec()方法。 2.编译IDL接口D:\corba1>idlj –fall counter.idl 编译接口将自动生成CounterApp包,含有以下源文件: _CounterStub.java Counter.java CounterHelper.java CounterHolder.java CounterOperations.java CounterPOA.java ①_CounterStub.java类继承了org.omg.CORBA.portable.ObjectImpl类,是客户端类,用于接受本地的自增inc()方法和自减dec()方法的调用,为客户端提供CORBA 服务功能,实现了Counter.java的接口。 ②Counter.java源文件是IDL接口的java语言实现。 ③CounterHelper.java中的抽象类CounterHelper提供了辅助的方法,将CORBA对象引用转化成合适的类型。 ④CounterHolder.java源文件中CounterHolder类是最终类。 ⑤CounterOperations.java 是java语言描述的IDL接口。 ⑥CounterPOA.java是服务端的skeleton类,实现了服务端的接口,为服务端提供CORBA 服务功能。编写并编译对象实现代码:CounterImpl.java。CounterImpl中编写了自增和自减的方法。编写并编译服务端程序: Server.java。服务端程序Server.java中引入了要使用的包,声明服务应用类并编写main代码块,main方法中try代码块需要建立ORB对象,同时使用ORB的名字服务寻找对象,等待客户调用。 5 编写并编译客户端程序: Client.java。客户端程序中引入了要使用的包,并声明客户应用类,编写main方法,在try代码块中建立ORB对象,使用ORB的名字服务寻找counter对象,调用自增自减方法,把服务端返回的内容显示在屏幕上。2.3详细实现 (1)题目一Helloworld代码块实现 客户端类:
import sample.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class HelloWorldClient { public static void main(String args[]) { try{ 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}; HelloWorld helloWorld = HelloWorldHelper.narrow(ncRef.resolve(path)); String hello = helloWorld.sayHello(); System.out.println(hello); } catch (Exception e) { System.out.println("ERROR : " + e) ; e.printStackTrace(System.out); } } }服务端类: i
mport sample.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.CORBA.portable.*; import org.omg.PortableServer.*; class HelloWorldServant extends HelloWorldPOA{ //对象实现类 public String sayHello(){ return "\nHello World!\n"; } } public class HelloWorldServer{ //服务程序 public static void main(String args[]){ try{ //初始化ORB ORB orb = ORB.init(args, null); //取根POA的引用 org.omg.CORBA.Object poaobj = orb.resolve_initial_references ("RootPOA"); org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(poaobj); org.omg.PortableServer.POAManager manager = rootPOA.the_POAManager(); //创建伺服对象 HelloWorldServant objRef = new HelloWorldServant(); HelloWorld obj = objRef._this(orb); //绑定命名服务 NamingContext ncRef = NamingContextHelper.narrow(orb.resolve_initial_references("NameService")); NameComponent nc = new NameComponent("Hello", ""); NameComponent path[] = {nc}; ncRef.rebind(path, obj); //激活POA管理器 manager.activate(); //等待处理客户程序的请求 System.out.println("HelloWorld is running!"); orb.run(); }catch (Exception e) { System.err.println("ERROR: " + e); e.printStackTrace(System.out); } } }(2)题目二Counter代码块实现 对象实现:
import CounterApp.*; public class CounterImpl extends CounterPOA { private int count; public CounterImpl(){ count = 0; } public void inc(){ count++; } public void dec(){ count - -; } public int value(){ return count; } }客户端类:
import CounterApp.*; import java.util.*; import java.io.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; public class Client { public static void main(String[] args){ try{ ORB orb = ORB.init(args, null); org.omg.CORBA.Object obj = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(obj); NameComponent nc = new NameComponent("Count",""); NameComponent path[] = {nc}; String ref = null; try{ Scanner reader = new Scanner(new File("Counter.ref")); ref = reader.nextLine(); }catch(IOException ex){ System.out.println("File error: "+ex.getMessage()); System.exit(2); } obj = orb.string_to_object(ref); if(obj == null){ System.out.println("Invalid IOR"); System.exit(4); } Counter c = null; try{ c = CounterHelper.narrow(obj); }catch(BAD_PARAM ex){ System.out.println("Narrowing failed"); System.exit(3); } int inp = -1; do{ System.out.print("Counter value: "+c.value()+"\nAction(+/-/e)?"); System.out.flush(); do{ try{ inp = System.in.read(); }catch(IOException ioe){} }while(inp != '+' && inp != '-' && inp != 'e'); if(inp == '+') c.inc(); else if(inp == '-') c.dec(); }while(inp != 'e'); }catch(Exception ex){ System.out.println("Exception: "+ex.getMessage()); System.exit(1); } } }服务端类:
import CounterApp.*; import java.io.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import org.omg.CORBA.portable.*; import org.omg.PortableServer.*; public class Server { public static void main(String[] args){ try{ ORB orb = ORB.init(args, null); org.omg.CORBA.Object poaobj = orb.resolve_initial_references ("RootPOA"); org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(poaobj); org.omg.PortableServer.POAManager manager = rootPOA.the_POAManager(); CounterImpl c_impl = new CounterImpl(); Counter c = c_impl._this(orb); NamingContext ncRef = NamingContextHelper.narrow(orb.resolve_initial_references("NameService")); NameComponent nc = new NameComponent("Count", ""); NameComponent path[] = {nc}; ncRef.rebind(path, c); FileOutputStream file = new FileOutputStream("Counter.ref"); PrintWriter writer = new PrintWriter(file); String ref = orb.object_to_string(c); writer.println(ref); writer.flush(); file.close(); System.out.println("Server started."+" Stop:Ctrl-c"); rootPOA.the_POAManager().activate(); orb.run(); }catch(IOException ex){ System.out.println("File error:"+ex.getMessage()); System.exit(2); }catch(Exception ex){ System.out.println("Exception: "+ex.getMessage()); System.exit(1); } } }三.组件图
四.调试及测试截图 1.Helloworld (1)编译HelloWorld的idl接口 自动生成sample包 (2)启动名字服务器: (3)启动服务端程序: (4)启动客户端程序 2.Counter (1)编译counter的idl接口 自动生成CounterApp包 (2)启动名字服务器: (3)启动服务端程序: (4)启动客户端程序:(进行自加自减操作) 3.开始进行用javac编译java程序时,总是会显示无法识别的符号,通过问同学了解到是java的JDK版本配置的问题,最后又重新配置了java的JDK环境,最终程序顺利运行。 参考:https://blog.csdn.net/a19990412/article/details/81272909
五.个人总结 (1)开始时总是提示java无法识别的内部命令,最后通过重新下载配置了JDK才成功解决了这个问题,将java的JAVA_HOME,path和classpath环境配置好是java程序实现的关键步骤,通过此次的实验,让我更加熟悉java环境的配置问题,为以后的java学习奠定一定的基础。 (2)开始进行上机实验时,不能清楚的理解CORBA组件模型,通过此次上机实验让我对此有了更加深入的理解,CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构,通用对象请求代理体系结构)是由OMG组织制订的一种标准的面向对象应用程序体系规范。或者说 CORBA体系结构是对象管理组织(OMG)为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案,是一种远程分布式方法调用,是服务端和客户端传输数据的方式,使用corba的组件模型,易于扩充和修改,具有较高的通用性和适应性;易于构造组装,具有规范的外部接口。
参考资料: (Java JDK环境配置)https://blog.csdn.net/a19990412/article/details/81272909 (CORBA学习)https://baike.baidu.com/item/CORBA/2776997?fr=aladdin (组件化开发方法)https://blog.csdn.net/blog_jihq/article/details/79191008 https://www.zhihu.com/question/29735633/answer/90872147