在本文中,我将说明如何从一个非JAVA语言编写的应用中访问EJB。更加特别地是,我将讨论从一个CORBA的C++客户端访问会话和实体 Bean(它使用同步的IIOP协议进行通信)。我没有提到消息驱动Bean,尽管你可能想从其它语言编写的应用中使用MOM产品来访问它们。
1. RMI-IIOP
会话Bean和实体Bean使用远程方法调用(RMI)来进行同步通信。J2EE1.3要求JAVA客户端使用RMI-IIOP。RMI- IIOP采用CORBA的IIOP协议,这使得RMI-IIOP与CORBA相兼容。换句话说,不是基于JAVA开发的客户端可以通过CORBA与EJB 进行通信。
要实现这点,你必须使用符合J2EE1.3的应用服务器。以前的EJB规范没有要求你去用RMI-IIOP协议。而是,应用服务器采用了RMI- JRMP或是其它私有协议。另外,你必须使用符合CORBA2.3.1或更高版本的ORB。以前的CORBA版本没有实现与RMI-IIOP协议进行互操 作所必需的规范,尤其是后来集成中CORBA规范和JAVA到IDL的语言映射规范中的用值传递对象的规范(可以参看CORBA/IIOP规范2.6版, 在"值类型语义"一章)。
值类型语言增加了用值来传递对象的概念,是由RMI引来,加入到CORBA中的。CORBA最初并不支持这项功能;但是,这个概念对于实现JAVA与CORBA之间的互操作是至关重要的。
JAVA到IDL语言映射规范定义了如何把JAVA接口映射到CORBA的IDL语言。这个定义使CORBA分布对象可以访问本来不具有 CORBA的IDL的EJB(还有那些RMI-IIOP分布对象)。特别的是,这个规范定义了一个JAVA的RMI子集,叫RMI/IDL,它可以让你
映射到IDL,用IIOP(或是更通用,是GIOP协议)作为通信的底层协议。
2. RMI/IDL
许多RMI/IDL数据类型遵循一定的约束;我们来看一下那些最重要的类型。更详细的信息,请参看JAVA到IDL的语言映射规范。
表1显示了JAVA基本类型到IDL的映射。
表1:JAVA到IDL的映射
Java OMG IDL
void void
boolean boolean
char wchar
byte octet
short short
int long
long long long
float float
double double
JAVA包映射为IDL的模块。RMI/IDL中的远程接口映射为IDL的接口并具有相对应的名字。但是,那些用JavaBean命名方式用来只读或读写属性的方法被映射为IDL的属性。后面我将提到这个。
JAVA中可序列化的对象映射为CORBA的值类型。值类型为CORBA提供了用值来进行传递的语义。值类型是属于本地的,不能被远程调用。它们 不注册到ORB中,也不需要标识符,因为它们的值就是它们的标识符。更详细的信息,请参阅《Professional J2EE EAI》和CORBA/IIOP规范2.6版。
就象我已经提到过的,所有的JAVA或序列化的对象,包括JAVA固有的和用户定义的,都将映射为值类型。但是,这个规则也有一些例外----例 如,当你想把java.lang.String映射到IDL时。如果把它定义为常量(final static),这个对象将被映射为IDL的wstring。在其它情况下,包括作为方法的参数或返回值,该对象都被映射为值类型CORBA:: WStringValue。这个值类型是CORBA模块的一部分,它的IDL定义如下:
valuetype WStringValue wstring;
这等同于下面的IDL定义:
valuetype WStringValue {
public wstring data;
};
但是,要记住,第一种定义能够更干净地映射到JAVA。表2列出其它特殊的映射情况。
表2:其它重要的特殊映射情况
Java OMG IDL
java.lang.Object ::java::lang::_Object
java.lang.String ::CORBA::WStringValue or wstring
java.lang.Class ::javax::rmi::CORBA::ClassDesc
java.io.Serializable ::java::io::Serializable
java.io.Externalizable ::java::io::Externalizable
java.rmi.Remote ::java::rmi::Remote
org.omg.CORBA.Object Object
3. 实现集成
后面我将返回来讨论值类型,先讨论用户定义的类,再讨论内嵌的类,如Vectors、Collections和Enumerations。现在, 让我们看一下CORBA和EJB集成的基本方式。首先,我们需要一个EJB。在第一个例子中,我们使用一个简单的会话Bean,它只使用简单的数据类型作 为方法的参数和返回值。我们没有强行去用值类型。(注意:从CORBA客户端访问实体Bean跟访问会话Bean的过程一样。)
这个方式是最简单的;但是,你不能把它用在复杂的接口上。它的好处是:你可以使用不支持值类型的ORB。许多CORBA产品都是这样(不支持值类型),尤其是那些不是用C++实现的产品。
这个例子中,我将使用C++版本的ORBacus4.1.0作为CORBA的ORB,使用VC++6.0作为编译客户端代码的编译器。为部署这个 例子中的EJB,我将使用JBoss3.0.0。你可以从网上下载ORBacus4.1.0(也可以从IONA网站上下载)和JBoss3.0.0。
你可以使用任何支持CORBA2.3.1或更高版本的ORB产品(只要它支持到C++的映射)、一个相对应的C++编译器和一个支持J2EE1.3规范的应用服务器。理论上讲不需要修改代码;但是,如果你使用其它产品,小的改动可能是必要的。
4. EJB会话Bean
让我们简单地看一下这个名叫CorbaEai的会话Bean。在我们的第一个例子中,这个简单的远程接口包含一个计算两个整数之和的简单方法。
package eai;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface CorbaEai extends EJBObject {
public int sum(int a, int b) throws RemoteException;
}
在你熟悉了集成过程之后,我将告诉你如何扩展这个接口以包含使用用户定义的对象和
1. RMI-IIOP
会话Bean和实体Bean使用远程方法调用(RMI)来进行同步通信。J2EE1.3要求JAVA客户端使用RMI-IIOP。RMI- IIOP采用CORBA的IIOP协议,这使得RMI-IIOP与CORBA相兼容。换句话说,不是基于JAVA开发的客户端可以通过CORBA与EJB 进行通信。
要实现这点,你必须使用符合J2EE1.3的应用服务器。以前的EJB规范没有要求你去用RMI-IIOP协议。而是,应用服务器采用了RMI- JRMP或是其它私有协议。另外,你必须使用符合CORBA2.3.1或更高版本的ORB。以前的CORBA版本没有实现与RMI-IIOP协议进行互操 作所必需的规范,尤其是后来集成中CORBA规范和JAVA到IDL的语言映射规范中的用值传递对象的规范(可以参看CORBA/IIOP规范2.6版, 在"值类型语义"一章)。
值类型语言增加了用值来传递对象的概念,是由RMI引来,加入到CORBA中的。CORBA最初并不支持这项功能;但是,这个概念对于实现JAVA与CORBA之间的互操作是至关重要的。
JAVA到IDL语言映射规范定义了如何把JAVA接口映射到CORBA的IDL语言。这个定义使CORBA分布对象可以访问本来不具有 CORBA的IDL的EJB(还有那些RMI-IIOP分布对象)。特别的是,这个规范定义了一个JAVA的RMI子集,叫RMI/IDL,它可以让你
映射到IDL,用IIOP(或是更通用,是GIOP协议)作为通信的底层协议。
2. RMI/IDL
许多RMI/IDL数据类型遵循一定的约束;我们来看一下那些最重要的类型。更详细的信息,请参看JAVA到IDL的语言映射规范。
表1显示了JAVA基本类型到IDL的映射。
表1:JAVA到IDL的映射
Java OMG IDL
void void
boolean boolean
char wchar
byte octet
short short
int long
long long long
float float
double double
JAVA包映射为IDL的模块。RMI/IDL中的远程接口映射为IDL的接口并具有相对应的名字。但是,那些用JavaBean命名方式用来只读或读写属性的方法被映射为IDL的属性。后面我将提到这个。
JAVA中可序列化的对象映射为CORBA的值类型。值类型为CORBA提供了用值来进行传递的语义。值类型是属于本地的,不能被远程调用。它们 不注册到ORB中,也不需要标识符,因为它们的值就是它们的标识符。更详细的信息,请参阅《Professional J2EE EAI》和CORBA/IIOP规范2.6版。
就象我已经提到过的,所有的JAVA或序列化的对象,包括JAVA固有的和用户定义的,都将映射为值类型。但是,这个规则也有一些例外----例 如,当你想把java.lang.String映射到IDL时。如果把它定义为常量(final static),这个对象将被映射为IDL的wstring。在其它情况下,包括作为方法的参数或返回值,该对象都被映射为值类型CORBA:: WStringValue。这个值类型是CORBA模块的一部分,它的IDL定义如下:
valuetype WStringValue wstring;
这等同于下面的IDL定义:
valuetype WStringValue {
public wstring data;
};
但是,要记住,第一种定义能够更干净地映射到JAVA。表2列出其它特殊的映射情况。
表2:其它重要的特殊映射情况
Java OMG IDL
java.lang.Object ::java::lang::_Object
java.lang.String ::CORBA::WStringValue or wstring
java.lang.Class ::javax::rmi::CORBA::ClassDesc
java.io.Serializable ::java::io::Serializable
java.io.Externalizable ::java::io::Externalizable
java.rmi.Remote ::java::rmi::Remote
org.omg.CORBA.Object Object
3. 实现集成
后面我将返回来讨论值类型,先讨论用户定义的类,再讨论内嵌的类,如Vectors、Collections和Enumerations。现在, 让我们看一下CORBA和EJB集成的基本方式。首先,我们需要一个EJB。在第一个例子中,我们使用一个简单的会话Bean,它只使用简单的数据类型作 为方法的参数和返回值。我们没有强行去用值类型。(注意:从CORBA客户端访问实体Bean跟访问会话Bean的过程一样。)
这个方式是最简单的;但是,你不能把它用在复杂的接口上。它的好处是:你可以使用不支持值类型的ORB。许多CORBA产品都是这样(不支持值类型),尤其是那些不是用C++实现的产品。
这个例子中,我将使用C++版本的ORBacus4.1.0作为CORBA的ORB,使用VC++6.0作为编译客户端代码的编译器。为部署这个 例子中的EJB,我将使用JBoss3.0.0。你可以从网上下载ORBacus4.1.0(也可以从IONA网站上下载)和JBoss3.0.0。
你可以使用任何支持CORBA2.3.1或更高版本的ORB产品(只要它支持到C++的映射)、一个相对应的C++编译器和一个支持J2EE1.3规范的应用服务器。理论上讲不需要修改代码;但是,如果你使用其它产品,小的改动可能是必要的。
4. EJB会话Bean
让我们简单地看一下这个名叫CorbaEai的会话Bean。在我们的第一个例子中,这个简单的远程接口包含一个计算两个整数之和的简单方法。
package eai;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface CorbaEai extends EJBObject {
public int sum(int a, int b) throws RemoteException;
}
在你熟悉了集成过程之后,我将告诉你如何扩展这个接口以包含使用用户定义的对象和