基于jCOM搭建Java-微软信息桥梁

基于jCOM搭建Java-微软信息桥梁

一、jCOM简介

Gartner的研究分析,在名列全球前1000名的企业中,大约90%都混合应用了JavaWindows技术。然而,Java技术和微软技术分别提供了丰富但却迥然不同的解决方案,或至少说这两种方案之间的差异是巨大的。

为了解决这一矛盾,Sun率先提出了JNI解决方案。JNI,即Java本机接口,是编写Java本机方法和把Java虚拟机嵌入到本机应用程序中的标准编程接口。Java本机接口的主要目的就是保证本机方法库在不同平台上的Java虚拟机中的二进制兼容性。使用JNI编写程序,就可以很方便地做到程序的跨平台可移植。尽管如此,Sun提供的JNI解决方案只是底层的API包装,在实际开发中用到大量Java/COM互操作时,直接从JNI级进行开发显然效率并不高。

为此,大大小小的公司甚至个人都试图提供全部或局部的Java/COM互操作解决方案。例如,WebLogic提供的jCOM技术,bridge2javaIBM提供的基于Java本机接口和COM技术,允许把ActiveX对象容易地集成到Java环境中),jacoZoom(是一个java类库它允许你在java程序中使用ActiveX控件和ActiveX服务器,基于Java本机接口和COM技术,允许使用于Windows平台上的任何java环境中),J-Integra for COMhttp://j-integra.intrinsyc.com/),还有一个小型的JCom桥接库(http://sourceforge.net/projects/jcom/,它也支持从Java中调用COM对象,例如EXCEL工作簿,VBCOM对象等)。其中,WebLogic提供的jCOM技术为微软的COM对象和Java对象提供一个稳定、无缝的机制,让这两种对象可以协同工作。

jCOM ,即JavaCOM桥,它是一种用软件实现的桥接机制,可以帮助Java应用程序快速访问微软的COMDCOM组件。而且,微软的COM应用程序也可以通过这个机制访问基于Java的对象。jCOM不仅具有实现相对简单的特点,而且其最吸人的部分在于它的透明性。对Java程序员来说,COM对象看起来与其他Java对象没有什么不同。而对COM开发人员来说,远程Java对象看起来就象是本机COM组件。在这些对象中可以找到jCOM运行时刻引擎进行动态类型映射,因此从表面上屏蔽了数据类型间的差异。远程对象的数据类型被动态地转换成调用程序所使用的基元类型。对Java开发人员来说,COM数据类型表现得就象Java基元类型;而对COM开发人员来说,Java数据类型看起来就象是COM数据类型。

本文将重点讨论BEAJava/COM解决方案。

二、jCOM工作原理

jCOM 声称以双向方式工作,实际只是允许在JavaCOM组件之间,在任意一个方向上通信—Java对象可以调用COM组件,COM组件又可以调用Java对象。当然,在这两种不同的分布式组件框架之间,有着两种截然不同的底层体系结构负责线路级通信。在运行时,jCOM内部设置了一个双协议栈环境,实现对底层两个彼此独立的基础结构的支持(参考图1)。对于COM组件,有一个在DCE远程过程调用之上的COMDCOM实现。对于Java对象,有一个在Java远程方法IIOPInternet Inter-ORB)之上的远程方法调用(RMI)实现。调用要通过这些协议栈,并通过内部的协议转换进行处理,内部的协议转换能够有效地屏蔽掉低一级的协议。对于EJB来说,来自COM客户的调用看起来就好像是来自Java客户的调用。对于COM组件来说,来自Java客户的调用看起来就好象是来自一个普通的COM客户。

jCOM 提供了能够自动生成更高级别COMDCOM代理以及RMI存根的工具。客户程序用COMDCOM代理以及RMI存根在这两个不同的基础结构间封装并传送调用。jCOM可以设置成本机模式,这样就可以利用本机操作系统的动态链接库,从而减轻DCOM的网络负荷,并极大地提高系统性能。

下面看一下Java对象如何调用COM对象:

import com.jCOM Sam ple.account.*;

clsaccount account=new clsaccount();

double accountbalance=getaccountbalance("Xiao Wang");

1演示了当Java对象访问COM组件的时候事件产生的标准流程。首先,jCOM为要访问的COM组件生成个代理对象,Java对象开始调用这个代理对象。然后,代理对象与jCOM运行时引擎通信,jCOM运行时引擎又把代理对象的消息封装成远程过程调用的COMDCOM形式,通过TCPIP发送到Windows环境里的COM组件。在最低的一层上,jCOM使用服务器上的标准Java网络类进行调用。



1.jCOM运行时刻环境 点击看原图

三、使用jCOM工具

在实际开发中,除了使用WebLogic中的一些配置外,多数情况下还需要使用jCOM提供的工具程序。这些程序是jCOM的核心,在不同平台间公开对象时,要用这些工具建立、部署所需要的元素。其中,常用的有:com2javajava2comregjvmregtlb等。篇幅所限,在此仅介绍后面示例中直接用到的com2java

com2java 的作用是,建立访问COM组件所需要的Java代理代码模块。

所有的COM对象都有与其相关的类型库,类型库可以独立存在,或者在其它文件里,它们定义组件所包含的接口和类。不过,要找到和一个组件相关的类型库并不太容易。这是因为,类型库(扩展名为.tlb.olb,代表类型库)有可能包含在其它文件里,比如DLL文件里,而在Visual Basic里,类型库则保存在应用程序可执行文件自身中。

找到需要公开出来的COM组件所在的类型库之后,要把它交给com2java处理,让com2java生成对应的Java类,供Java客户一端使用。com2java会扫描类型库,寻找它能找到的所有枚举、COM接口以及COM类。

下面我们看一下com2java根据类型库里找到的内容为COM建立的类。

对于从类型库中找到的每个枚举,会建立一个Java接口,里面包含常量声明,每个常量对应枚举中的一个项目。对于从类型库中找到的每个COM类,会建立一个对应的Java类,类名称与COM类相同。这些类是客户程序通常要调用的类。

com2java 会为从类型库里找到的每个接口建立Java接口和Java类。生成的Java接口的名称与COM接口的名称相同,Java类的名称也与COM接口的名称相同,只是在类名称最后加上Proxy这个后缀,表示这是一个代理类。例如,如果有一个COM接口,名字是WindowsHelper,那么生成的Java接口名称就是WindowsHelper,而实现类(实现这个接口)的名称就是WindowsHelperProxy。可以想象,生成的Java接口能把COM接口映射成Java可以识别的格式,而生成的对应的Java代理类可以访问实现这个COM接口的COM对象。

其实,除了前面介绍的功能之外,COM组件也可以通过com2java生成的Java类访问实现这个接口的Java对象中的方法。com2java的这种用途是com2java的特殊用法。

com2java 既有GUI版本,也有命令行版本。可以在\beawebloogic81serverbin目录下找到com2java.EXE(GUI版本)com2javacmdexe(命令行版本)

【导读】第一部分析了 BEA 提供的 Java COM 互操作解决方案 —jCOM 的实现原理;本文是第二部分,比较全面地分析了 Weblogic Server jCOM 实现技术之后,通过一个具体实例来说明了 jCOM 的具体使用过程。

WebLogic Server 8.1 的发行包中带有大量参考示例,其中有专门供jCOM使用的示例,但遗憾的是这些全部的jCOM示例,演示的都是用基于COM的前端访问WebLogic Server上基于EJB的后端。故本文中仅提供从Java前端访问基于COM的后端的示例。

在本例中,我们构建一个简单的银行帐户接口应用程序。在这个程序中,我们用JSP程序从前端访问服务器上COM组件里包含的业务逻辑。我们假定在用户计算机上已经安装了WebLogic Server服务器。

一、建立JSP前端

首先,要为银行帐户应用程序建立JSP前端。为简单起见,我们把表示层和业务逻辑层都一起包含到了BankAccount.jsp应用中(在使用本文源代码时,只需把解压后得到的BankAccount.jsp源文件复制到%WEBLOGIC_HOME%\ sam ples\server\examples\build\examplesWebApp目录下)。第一件需要注意的是,从Java的角度来看,引入要调用的COM组件时,没有用任何Java认识的方法,使用的就是一个正常的Java类。访问COM组件的所有底层代理机制,从表面来看都被隐藏了。实际开发中,我们一般把业务逻辑从BankAccount.jsp分离出来,以Servlet的形式放在中间层;但是在此为了演示的方便性,我们把表示层和业务层都放在jsp文件里了。请参考列表1中的代码片断。

列表1.BankAccount.jsp(在此仅列出主要代码片断)

<%! Private clsAccount account; %>

<% //
创建一个Account COM组件并把一个指向它的句柄放入session

Account=(clsAccount)session.getAttribute(“objAccount”);

if(account==null)

account=new clsAccount();

//
会话期间跟踪所有的用户信息

Vector messages=(Vector)session.getAttribute(“messages”);

if(messages=null)

messages=new Vector();

//
取得表单变量

String accountName=request.getparameter(“accountName”);

Boolean NEW_ACCOUNT=true;

if(accountName==null)

accountName=””;

else

NEW_ACCOUNT=accountExists(accountName);

二、建立后端帐户COM组件

接下来,要建立后端的银行账户COM组件。为了简化,本示例假定和COM组件在同一台计算机上运行并且选用Visual Basic 6.0来创建这里的银行账户COM组件。

1. 启动Visual Basic,新建一个ActiveX Dll项目。

2.
把项目名称修改为Account,类名设置为clsAccount

3.
clsAccount类中建立如下代码:

														
																'定义全局变量
														
																

Private mstrAccountNames(1 To 100) As String

Private mdblAccountBalances(1 To 100) As Double

Public Property Get AccountNames()

AccountNames = mstrAccountNames

End Property

Public Property Get AccountBalances()

AccountBalances = mdblAccountBalances

End Property

'
创建一个新帐户

Public Function Create(accountName As String, amount As Double) As Integer

Dim i As Integer

Dim flag As Boolean

i = 1

Do While (True)

If mstrAccountNames(i) = "" Then

Create = i

mstrAccountNames(i) = accountName

mdblAccountBalances(i) = amount

Exit Do

End If

i = i + 1

If i > 100 Then

Exit Do

End If

Loop

End Function

‘…………(
篇幅所限,在此省略,详见所附VB源文件)



4.
单击菜单文件-项目另存为,把项目保存在D:\myex\jCOM\Bank Sam p目录下。

5.
在文件菜单中,单击“Make Account.dll”,建立组件的动态链接库。

三、在服务器上安装COM组件

在服务器上安装COM需要好几项操作。上面创建的COM组件要通过jCOM公开给Java客户机,然后,Java对象即可以象调用其它Java类一样调用这个COM组件。

1.
注册组件

我这里试验用的服务器为Windows 2000 Server。在Windows上注册COM组件是非常简单的事情,只需使用下列命令:

Regsvr32 Account.dll /s

2.
设置组件服务

在这个示例中,我们所用的操作系统是简体中文Windows 2000 Server(以下步骤可能因OS的不同而有所不同),可以按如下步骤在计算机上设置组件服务:

1.
控制面板管理工具下,打开组件服务

2.
组件服务控制台里,依次展开组件服务->计算机我的电脑,选择“COM+应用程序,在菜单里选择操作->新建->应用程序,建立一个空的服务器应用程序,应用程序名称为jCOM

3.
组件服务里,右键单击刚建立的应用程序上,在菜单中选择属性,在安全设置选项卡里选择仅在进程级执行访问检查,然后把调用的身份验证级设置为连接

4.
下一步,打开“jCOM”目录下的组件目录。把刚刚建立的Account.dll组件文件拖动到这个组件目录下。

3. com2java生成代理文件

在设置服务器之前要做的最后一步就是生成jCOM中间件,用它把前后端各层连接起来。请遵循如下步骤生成中间件:

1.
进入%WEBLOGIC_HOME%\server\bin目录下,运行com2java.exe

2.
选择刚才创建的Account.dll作为要扫描的类型库。

3.
com.jCOM Sam ple.account作为包名称。

4.
单击“Generate Proxies”,选择一个临时目录,保存程序生成的代理文件。

最后,com2java生成4个代理文件,用于在API一级访问银行账户COM组件之用。这4个代理文件分别是_clsAccount.java_clsAccountProxy.javaclsAccount.javaJintegraInit.java。编译这4个类,把它们放到WebLogic Server上示例应用程序能够访问到的目录中。

所有与jCOM相关的、编译时要使用的类,都保存在\bea\weblogic81\server\lib\weblogic.jar这个文件里。要确保在编译时,在类路径里引用这个JAR文件。

WebLogic Server上,建立目录结构\beaweblogic81\ sam ples\server\examples\build\examplesWebApp\WEBINF\classes\com\jCOM Sam ple\account,把4个编译好的类都放在这里,以便示例应用程序能够找到它们。

四、WebLogic Server设置

jCOM WebLogic Server 8.1一起安装,但是必须通过管理控制台激活。现在要做的是让应用程序能够调用COM

1.
打开管理控制台。

2.
在左边窗格里,单击Server,然后打开examples Server

3.
在右边窗格里,单击Protocols选项卡,然后jCOM选项卡。

4.
选中“Enable COM”复选框。

5.
单击Apply按钮。

6.
重新启动服务器。所做的设置在服务器重新启动后生效。

五、运行银行帐户客户端应用程序

打开浏览器,在地址栏中输入http://localhost:7001/examplesWebApp/BankAccount.jsp。观察实验结果,如果一切正常,你将会得到一个银行帐户接口数据操作表单。

在这个程序中,客户的请求由JSP页面处理,JSP页面通过clsAccount对象调用银行帐户COM组件。为了简单起见,在整个会话期间,所有数据都持久保存在COM对象中(在实际开发中,后端组件应该把信息缓存到数据库里)。

注意 如果你想修改前面用VB创建的COM组件,而且没有设置二进制兼容,那么必须重新运行com2java实用工具,以确保正确的代码同步。

总结

本文在较全面地分析了Weblogic ServerjCOM实现技术之后,通过一个具体实例来说明了jCOM的具体使用过程。

其实,Java/COM互操作是个相当复杂的主题,对市场上提供的各种方案的选用应视具体的环境而定。总之,如果想寻找一个稳定可靠的,而且无缝地在Java对象和微软COM对象之间通信的机制的话,我建议优先考虑jCOM

你可能感兴趣的:(基于jCOM搭建Java-微软信息桥梁)