Corba的学习笔记(二)
上次我们学习了Corba的一些基础,这次实验我们主要来学习jacorb的使用。
我们通过一个简单的程序调用远程对象的输出HelloWorld来学习jacorb的基本编程。
jacorb程序本身并不难,难点主要在配置上。当初刚学完Corba后感觉还是比较简单的,知道真的做起来才发现,配置环境是个大坑,稍有不慎就会导致错误。。
所以我们先从jacorb环境的配置讲起:
首先从官网http://www.jacorb.org/index.html 上下载JacORB,我下载的是3.3版本的。
通过查阅官方配置文档发现需要安装ant:
JacORB requires JDK 1.6 or above properly installed on your machine. To build JacORB (and compile the examples) you need to have the XML–based make tool “Ant” installed on your machine (version 1.7.1 or greater). Ant can be downloaded from http://ant.apache.org. All make ?les (build.xml) are written for this tool.
所以我们要进行ant的安装,在官网上下载Apache,我下载的是apache-ant-1.9.2。
将下载到的压缩包解压到任意目录下,Ant的配置非常简单,只需要将ant的安装目录添加到系统还击变量中即可。
计算机--属性--高级系统设置--环境变量,在系统变量中新建
1)ANT_HOME,输入ANT的安装目录;
2)在path目录中,添加:%ANT_HOME%\bin,
输入ant命令:如果是这样的,那就意味着配置成功。
在E 盘新建一个文件,命名为build.xml。
在E盘新建一个文件test.txt,可以随意输入一些内容。在dos命令下定位到E盘,输入ant命令,可以看到
3. 添加如下的系统环境变量
1) JACORB_HOME= C:\jacorb-3.3
2) Path环境变量添加%JACORB_HOME%/bin
3) CLASSPATH环境变量添加 C:\jacorb-3.3\lib;
C:\jacorb-3.3\bin的命令ns 用于启动命名服务(Naming Service),测试是否可以正常启动,在命令行下输入ns(由于在系统环境变量path中已经添加了C:\jacorb-3.3\bin,所以此命令在任何目录中都可以调用),显示如下图:第四步即是配置jacorb,更改properties文件即可。
配置完成后,我们要进行实际的编程了。
首先,我们要编译IDL文件,如下:
module
hello{interface HelloService{string sayHello();oneway void shutdown();};};
和我们上次讲的一样,IDL是一个接口定义语言,统一用IDL,可以消除语言差异性,这是RMI所达不到的。
module在相当于java中的pacege,而interface则相当于Java中的interface。
我们将上述文件命名为HelloService.idl,通过输入命令java -cp "C:\jacorb-3.3\lib\idl.jar" org.jacorb.idl.parser HelloService.idl会编译idl文件,
同时自动生成这些文件,包括POATie,Impl,stub,Helper,Holder等。
生成的这些文件,都是Corba运行所需要的,我们自己需要编写接口HelloService的实现类,以及客户端和服务端。
下面分别编写这三个文件:
//HelloService接口的实现类
package hello; import org.omg.CORBA.ORB; public class HelloServiceImpl extends HelloServicePOA{ private ORB orb ; public void setORB(ORB orb_val){ orb = orb_val ; } public String sayHello(){ return "\nHello World!!!\n"; } public void shutdown(){ orb.shutdown(false); } }
//服务器端
package hello; 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; public class HelloServer { public static void main(String[] args) { try { // 创建和初始化ORB ORB orb = ORB.init(args, null); System.out.println("server--->11111"); // 获得根POA的引用,并且**POAManager POA rootpoa = POAHelper.narrow(orb .resolve_initial_references("RootPOA")); rootpoa.the_POAManager().activate(); System.out.println("server--->22222"); // 创建一个HelloServiceImpl对象,并且把它与ORB关联 HelloServiceImpl helloServiceImpl = new HelloServiceImpl(); System.out.println("server--->33333"); helloServiceImpl.setORB(orb); // 获得HelloServiceImpl对象的CORBA类型的对象引用 org.omg.CORBA.Object ref = rootpoa .servant_to_reference(helloServiceImpl); HelloService href = HelloServiceHelper.narrow(ref); System.out.println("server--->44444"); // 获得代表命名服务的Context org.omg.CORBA.Object objRef = orb .resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); System.out.println("server--->55555"); // 把HelloService对象与HelloService名字绑定 String name = "Helloservice"; NameComponent path[] = ncRef.to_name(name); ncRef.rebind(path, href); System.out.println("server--->66666"); System.out.println("HelloServer ready and wating......"); //等待客户端访问HelloService对象 orb.run(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("HelloServer Exiting..........."); } }
客户端文件//客户端
package hello; import org.omg.CORBA.ORB; import org.omg.CosNaming.NamingContextExt; import org.omg.CosNaming.NamingContextExtHelper; public class HelloClient { static HelloService helloServiceImpl ; public static void main(String[] args) { try { // 创建和初始化ORB ORB orb = ORB.init(args, null); // 获得代表命名服务的Context org.omg.CORBA.Object objRef = orb .resolve_initial_references("NameService"); NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef); // 获得名为"HelloService"的HelloService对象的远程引用 String name = "Helloservice"; helloServiceImpl = HelloServiceHelper.narrow(ncRef .resolve_str(name)); //调用HelloService对象的远程方法 System.out.println("obtained a handle on server object:" + helloServiceImpl); System.out.println(helloServiceImpl.sayHello()); helloServiceImpl.shutdown(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
编译所有java文件
这时,项目文件中的所有的.java文件都被编译成了.class文件。
接下来,通过命令start jaco hello.HelloServer来启动服务端。
注意!在进行上述这一系列的动作之前一定不要把ORB run的那个命令行关掉,一旦关掉,就相当于关闭了ORB服务,那么就会报如下错误;
这个错误困扰了我很长时间,在网上查阅了各种资料,使用了各种方法,像什么
tnameserv -ORBInitialPort 端口号这些都尝试了一遍,结果都没什么用。
直到最后,才发现原来是ORB服务关了,怪不得一直是连接不到端口!
服务器启动后,正确的状态应该是下图所示:
下面,再用同样的方式启动客户端:
客户端显示Hello,运行成功!