背景:项目上使用到了CORBA这个古老的东东,所以需要学习一下。
CORBA的一些资料,童鞋们可以自己看,我就不贴在这里了
<<CORBA Programming with J2SE 1.4>>
<<CORBA Technology and the Java™ Platform Standard Edition>>
按照我的理解,CORBA是一种技术,可以让你在一台机器上,通过CORBA进行远程调用。
例如我在机器A上写了一个函数,实现a+b,然后通过CORBA发布我的接口;那么在机器B上,通过CORBA相关接口,可以调用机器A上的实现。
目前有很多种远程调用技术,参见 http://www.open-open.com/lib/view/open1353459989623.html
为什么项目中不使用新的远程调用技术/方案呢,主要是我们的代码是遗传下来的。。。。。。太坑了。。。。。。
JAVA Corba标准的实现主要有(我了解到的)JDK自己的实现,和Jacorb的实现,这里我就用JDK自带的做演示了...
用JDK写Corba程序和用Jacorb写有些许区别
万能的HelloWorld
代码一:写接口
首先需要些一个接口Interface,在接口里面定义你想要参与/允许/提供远程调用的方法。
规则:
1. 这个接口必须继承java.rmi.Remote
2. 公开的方法必须抛出RemoteException
package com.corba;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloInterface extends Remote {
public void sayHello(String guest) throws RemoteException;
}
代码二:实现接口
注意:
1. 继承PortableRemoteObject吧,如果不继承,那么需要写一堆初始化的东东...你可以去看下PortableRemoteObject构造函数的实现,太复杂了。通过简单继承PortableRemoteObject,HelloImpl这个类就可以用在基于IIOP协议的远程调用上了。
原理:为了实现远程调用,我们每个实例化(new HelloImpl())都需要经过export和发布两个流程,这样远端才可以通过我们发布出去的实例,来进行调用。当然你也可以自己写export的代码。继承PortableRemoteObject后,你每一次实例化( new HelloImpl() )都会自动export
构造函数中的super()是可以删除的,写上去只是为了提醒童鞋们,父类做了很多工作,不要忘了。
package com.corba;
import javax.rmi.PortableRemoteObject;
public class HelloImpl extends PortableRemoteObject implements HelloInterface {
public HelloImpl() throws java.rmi.RemoteException {
super(); // invoke rmi linking and remote object initialization
}
public void sayHello(String guestName) throws java.rmi.RemoteException {
System.out.println("Hello, " + guestName + "!");
}
}
代码三:写Corba Server,发布服务
package com.corba;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
public class HelloServer {
public static void main(String[] args) {
try {
// Step 1: Instantiate the Hello servant
HelloImpl helloRef = new HelloImpl();
// Step 2: Publish the reference in the Naming Service
// using JNDI API
Properties environment = new Properties();
environment.setProperty("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
environment.setProperty("java.naming.provider.url", "iiop://localhost:1050");
Context initialNamingContext = new InitialContext(environment);
initialNamingContext.rebind("HelloService", helloRef);
System.out.println("Hello Server: Ready...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码四:测试客户端,用于测试上面提供的接口
package com.corba;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
public class HelloClient {
public static void main(String args[]) {
try {
Properties environment = new Properties();
environment.setProperty("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");
environment.setProperty("java.naming.provider.url", "iiop://localhost:1050");
Context initialNamingContext = new InitialContext(environment);
Object objref = initialNamingContext.lookup("HelloService");
HelloInterface hi = (HelloInterface) PortableRemoteObject.narrow(objref, HelloInterface.class);
System.out.println("Client: Obtained a ref. to Hello server.");
hi.sayHello(" MARS ");
} catch (Exception e) {
e.printStackTrace();
}
}
}
执行:
1.首先启动orbd服务, orbd端口为1050
2.运行HelloServer
运行HelloServer的时候会报错:
java.rmi.StubNotFoundException: Stub class not found: com.corba.HelloImpl_Stub; nested exception is:
java.lang.ClassNotFoundException: com.corba.HelloImpl_Stub
这是由于我们没有生成HelloImpl的辅助类(封装了Corba协议调用JAVA的细节)
生成方式如下:
a) 进入class目录(我建的是maven工程,如果是JAVA Project,那么class目录在CorbaHelloWorld/bin目录下),执行生成stub的命令 rmic -iiop com.corba.HelloImpl
b) 进入class所在目录,查看stub是否生成
c) 现在可以运行HelloServer了
3. 运行HelloClient
4. Server端的输出