Java调用Tuxedo方法

原文章地址


摘要:在以Tuxedo为中间件的企业信息系统中,为满足分布式系统的应用,需要解决在Java程序中调用Tuxedo服务的难题,给出了一种免费的、用Visual C++2、Visual Basic3、Jacob组件和Java语言结合编程的方法,详细地解说了方法实现的原理及关键程序代码。
  关键词:Java;Tuxedo服务;方法
  中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)17-31403-02
  A kind Of Method That Java Transfers Tuxedo Service
  DENG Zi-yun,CHEN Yu-lin,YANG Xiao-feng
  (Hunan Modern Logistics College, Changsha 410000,China)
  Abstract:In the enterprise information system that take Tuxedo as in the middleware, for satisfies the distributional system application, needs to solve the difficult problem in the Java program transfers the Tuxedo service, the article produced one kind free, with Visual C++, Visual Basic, the Jacob module and the Java language union programming method, detailed explained the method realization principle and the essential program code.
  Key words:Java;Tuxedo service;Method
  
  1 引言
  
  Tuxedo是一个标准的交易中间件,在金融、电信、社保等行业的信息系统应用广泛,以其为中心构建的应用系统采用三层体系结构,由Tuxedo完成数据的转发、事务处理、安全性控制、网络通信等功能。Java技术有各行各业的信息系统正被广泛应用,在许多用Java技术构建应用级程序的系统中需要在程序中调用Tuxedo的服务以完成数据的路由分发、数据存取等分布式环境下的功能。
  
  2 Tuxedo服务
  
  Tuxedo中间件以一个个的service来向连接它的各种系统提供各种功能的支持。它可以是多个Tuxedo中间件集成的域,在各个中间件服务器上装载有多个server(经过编译的可执行文件),server再分为更细的service。
  Tuxedo的service有两种调用接口:ATMI和CORBA(Common Object Request Broker Architecture, 公共对象请求代理体系结构)。在Tuxedo以往的版本中都支持ATMI接口,基于ATMI接口调用service的客户端可以用多种程序语言编写,如Delphi、VC、C、PowerBuilder等,而CORBA由于通信协议的复杂性和效率不高很少在工程应用场合中使用。
  service实际上就是一个个的用C语言或Pascal语言编写的函数,可以带有参数,其中指针及结构体的参数比较常用,用C或VC编写的客户端程序可以很方便地使用这些数据类型。调用Tuxedo的服务时必须考虑参数传递的问题,而VB、Java、PowerBuilder这些语言并不支持指针这种数据类型。
  
  3 调用方法原理
  
  如下图所示是一种Java调用Tuxedo服务的方法原理示意图。
  图1 调用方法原理示意图
  首先用VC编写DLL(Dynamic Link Library,动态链接库)。Tuxedo提供的ATMI接口DLL用C语言编写的,与VC可无缝集成;再用VB编写COM(Component Object Model,组件对象模型)组件;在Java中通过Jacob组件来调用COM组件来实现调用Tuxedo服务;Jacob是一种基于JNI(Java Native Interface,Java本地接口)技术的开源的在Java中调用COM组件的Java组件。这种方法的优势如下﹕
  (1)屏蔽了VB语言及Java语言不支持指针数据类型的问题;

        (2)用VC和VB编写的组件经过编译,有较好的执行效率;

  (3)组件式开发,封闭了调用Tuxedo服务的许多细节,在Java语言中只需声明对象,并执行对象的方法。
  
  4 调用方法的实现
  
  4.1 VC DLL实现
  VC支持三种DLL﹕Non-MFC Dll(非MFC动态库)、Regular Dll(常规DLL)、Extension Dll(扩展DLL)。Non-MFC DLL指的是不用MFC的类库结构,直接用C语言编写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用,Tuxedo的接口DLL就是这种,这里要编写的也就是这种。既然Tuxedo原有的调用接口DLL和要编写的DLL都是Non-MFC Dll,为什么不直接调用接口DLL呢?原因有两个:
  (1)原有接口中的函数参数有指针和结构体数据类型,在VB和ASP程序不支持指针数据类型,传递结构体数据数据不易实现;
  (2)原有接口函数的声明的调用约定为_cdecl,这种方式使得在VB程序在调用这些函数时参数的传递不正确,当有多个参数时在内存中的堆栈入栈的方向不同而导致内存出错,但在VC程序中可以正确使用。
  所以需在VC中编写DLL,声明调用Tuxedo接口函数的方法为_stdcall,在VB中即可正确使用,传递参数时只采用String及Long这种数据类型,防止参数传递的错误。编写DLL需在VC中用 Win32 Dynamic-Link Library方式新建一个Non-MFC Dll工程,主CPP文件中编写的调用服务的方法源代码如下﹕
  extern "C" _declspec(dllexport) long _stdcall vcCallTuxedoServiceToUpper(char *inBuff,char *outBuff)
  //inBuff为输入字符串,outBuff为返回字符串
  {char *sendBuff,*receiveBuff;
  long sendLen,recieveLen;
  int iRet;
  //初始化连接
  if(tpinit((TPINIT *)NULL)==-1)
  return -1;
  //给sendBuff及receiveBuff申请内存空间
  sendLen=strlen(inBuff);
  recieveLen=sendLen;
  if((sendBuff=(char *)tpalloc("STRING",NULL,sendLen+1))==NULL){
  tpterm();
  return -1;
  }
  if((receiveBuff=(char *)tpalloc("STRING",NULL,recieveLen+1))==NULL){
  tpfree(sendBuff);
  tpterm();
  return -1;
  }
  //拷贝输入字符串内容
  strcpy(sendBuff,inBuff);
  //调用转换大小写服务,第一个参数为服务名第二个参数为输入,第四个参数为输出
  iRet=tpcall("TOUPPER",(char *)sendBuff,0,(char **)&receiveBuff,&recieveLen,(long)0);
  if(iRet==-1){
  tpfree(sendBuff);
  tpfree(receiveBuff);
  tpterm();
  return -1;}
  strcpy(outBuff,receiveBuff);
  tpfree(sendBuff);
  tpfree(receiveBuff);
  tpterm();
  return 0;}
  当然需在机器上安装Tuxedo的客户端,设置好WSNADDR和TUXDIR系统变量,并在Tuxedo服务器端已经配置好TOUPPER service。上述程序注意要在工程Link设置中加入wtuxws32.lib及libwsc.lib,在VC编程环境的include设置中加入Tuxedo的安装目录下的include目录,LIB目录中加入Tuxedo的安装目录下的lib目录,并在需要调用Tuxedo服务的CPP文件首部加入如下语句﹕

  #include "atmi.h"
  本例中调用的是Tuxedo自带的大小写转换服务TOUPPER,实际应用中可更改程序中tpcall方法的第一个参数表示的服务名。
  4.2 VB COM组件实现
  由于VC中声明方法的方式为_stdcall,在VB中声明调用的方法会与VC中声明的方法名称有所不同,解决的办法有两个:
  (1)在VC编写DLL时用.def文件定义函数名。用.def文件能强制VC编程环境将输出函数的名称改成普通函数名称。
  (2)用一些DLL函数查看工具查看生成的DLL文件,如ViewDLL2.0,得到函数的声明情况,会发现函数名称在原有名称的基础上前多了一个”_”符号,后面多了”@num”,如本例中ΪvcCallTuxedoServiceToUpper@8,则在VB声明函数时,再alias此名称。声明如下所示﹕
  Private Declare Function vbCallTuxedoServiceToUpper Lib "vctuxedo" Alias "_ vcCallTuxedoServiceToUpper@8" (ByVal inBuff As String, ByVal outBuff As String) As Long
  声明方法类似于使用API函数。上述声明语句中,vctuxedo是在VC环境中生成的DLL文件的名称,应用时要与VB文件在同一路径或拷贝到系统路径中,如系统安装目录的system32目录;传递字符串时要使用byval传递方式。
  在VB中新建一个ActiveX DLL工程(工程名为tuxedo、类名为useClass),在生成的类中写入如下的源代码﹕
  Private Declare Function vbCallTuxedoServiceToUpper Lib "vctuxedo" Alias "_ vcCallTuxedoServiceToUpper@8" (ByVal inBuff As String, ByVal outBuff As String) As Long
  Function vbCallTuxedoServiceToUpper(byref inBuff as String) as string
  ‘在此加入处理代码
  dim sendString as string
  dim returnString as String
  sendString=inBuff
  returnString=space(len(inBuff)*2)
  if vbCallTuxedoServiceToUpper(sendString,returnString)=0 then
  ‘调用成功
  vbCallTuxedoServiceToUpper=returnString
  else
  ‘调用失败
  vbCallTuxedoServiceToUpper=”调用过程中发生错误”
  end if
  End function
  基于程序模块化和层次化设计思想的考虑,可以把一些业务逻辑和应用逻辑代码放在VB的COM组件函数中,在调用VC函数传递字符串参数时要注意字符串要初始化,字符串的长度要比VC中要求的长度长或相等,如果比VC中要求的长度小就会出现内存读写出错的情况,本例中为了保证字符串的长度,用len()函数求出长度后乘以2,并初始化为如此多个空格。这是因为VB中的len()函数不能得到字符串的精确长度,它把一个中文字符的长度计算成1,实际上要占2个字节,如果要得到精确长度,可用VC编写一个API函数,用VC的strlen() 函数即可。
  4.3 Java调用
  Java中调用COM组件的语句如下﹕
  import com.jacob.activeX.ActiveXComponent;
  import com.jacob.com.Dispatch;
  public class callTuxedo {
  public String callTuxedoService(String sendDoc){
  //找到组件
  ActiveXComponent mf = new ActiveXComponent("tuxedo.useClass");
  ObjectmyCom = mf.getObject();//生成一个对象

//调用组件的方法
  Objectresult=Dispatch.call(myCom," vbCallTuxedoServiceToUpper ",sendDoc);
  return result.toString();
  }
  public static void main(String[] args) {
  String sendDoc=new String("a test string.");//要转换的字符串
  String returnDoc=new String("");
  returnDoc=callTuxedoService(sendDoc);//调用服务,并得到返回的字符串
  …
  }}
  
  5 结束语
  
  本文用VC、VB、Jacob组件和Java语言结合编程的方法实现了在Java程序中调用Tuxedo服务。这种方法基于分层的构件化思想,比用Jolt、WTC方式调用Tuxedo服务实现节省了大量的资金(使用用Jolt必须购买此组件,使用WTC必须购买并安装Weblogic),并无需在Tuxedo中间件上开放JSL服务,为解决在Java程序中调用Tuxedo服务的问题提供了一种新的方法。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值