基于jCOM搭建Java-微軟信息橋梁
一、jCOM簡介
據Gartner的研究分析,在名列全球前1000名的企業中,大約90%都混合應用了Java和Windows技術。然而,Java技術和微軟技術分別提供了豐富但卻迥然不同的解決方案,或至少說這兩種方案之間的差異是巨大的。
為了解決這一矛盾,Sun率先提出了JNI解決方案。JNI,即Java本機接口,是編寫Java本機方法和把Java虛擬機嵌入到本機應用程序中的標準編程接口。Java本機接口的主要目的就是保證本機方法庫在不同平臺上的Java虛擬機中的二進制兼容性。使用JNI編寫程序,就可以很方便地做到程序的跨平臺可移植。盡管如此,Sun提供的JNI解決方案只是底層的API包裝,在實際開發中用到大量Java/COM互操作時,直接從JNI級進行開發顯然效率并不高。
為此,大大小小的公司甚至個人都試圖提供全部或局部的Java/COM互操作解決方案。例如,WebLogic提供的jCOM技術,bridge2java(IBM提供的基于Java本機接口和COM技術,允許把ActiveX對象容易地集成到Java環境中),jacoZoom(是一個java類庫—它允許你在java程序中使用ActiveX控件和ActiveX服務器,基于Java本機接口和COM技術,允許使用于Windows平臺上的任何java環境中),J-Integra for COM(http://j-integra.intrinsyc.com/),還有一個小型的JCom橋接庫(http://sourceforge.net/projects/jcom/,它也支持從Java中調用COM對象,例如EXCEL工作簿,VB的COM對象等)。其中,WebLogic提供的jCOM技術為微軟的COM對象和Java對象提供一個穩定、無縫的機制,讓這兩種對象可以協同工作。
jCOM
,即Java/COM橋,它是一種用軟件實現的橋接機制,可以幫助Java應用程序快速訪問微軟的COM/DCOM組件。而且,微軟的COM應用程序也可以通過這個機制訪問基于Java的對象。jCOM不僅具有實現相對簡單的特點,而且其最吸人的部分在于它的透明性。對Java程序員來說,COM對象看起來與其他Java對象沒有什么不同。而對COM開發人員來說,遠程Java對象看起來就象是本機COM組件。在這些對象中可以找到jCOM運行時刻引擎進行動態類型映射,因此從表面上屏蔽了數據類型間的差異。遠程對象的數據類型被動態地轉換成調用程序所使用的基元類型。對Java開發人員來說,COM數據類型表現得就象Java基元類型;而對COM開發人員來說,Java數據類型看起來就象是COM數據類型。
本文將重點討論BEA的Java/COM解決方案。
二、jCOM工作原理
jCOM
聲稱以雙向方式工作,實際只是允許在Java和COM組件之間,在任意一個方向上通信—Java對象可以調用COM組件,COM組件又可以調用Java對象。當然,在這兩種不同的分布式組件框架之間,有著兩種截然不同的底層體系結構負責線路級通信。在運行時,jCOM內部設置了一個雙協議棧環境,實現對底層兩個彼此獨立的基礎結構的支持(參考圖1)。對于COM組件,有一個在DCE遠程過程調用之上的COM/DCOM實現。對于Java對象,有一個在Java遠程方法IIOP(Internet Inter-ORB)之上的遠程方法調用(RMI)實現。調用要通過這些協議棧,并通過內部的協議轉換進行處理,內部的協議轉換能夠有效地屏蔽掉低一級的協議。對于EJB來說,來自COM客戶的調用看起來就好像是來自Java客戶的調用。對于COM組件來說,來自Java客戶的調用看起來就好象是來自一個普通的COM客戶。
jCOM
提供了能夠自動生成更高級別COM/DCOM代理以及RMI存根的工具。客戶程序用COM/DCOM代理以及RMI存根在這兩個不同的基礎結構間封裝并傳送調用。jCOM可以設置成本機模式,這樣就可以利用本機操作系統的動態鏈接庫,從而減輕DCOM的網絡負荷,并極大地提高系統性能。
下面看一下Java對象如何調用COM對象:
import com.jCOM |
圖1演示了當Java對象訪問COM組件的時候事件產生的標準流程。首先,jCOM為要訪問的COM組件生成—個代理對象,Java對象開始調用這個代理對象。然后,代理對象與jCOM運行時引擎通信,jCOM運行時引擎又把代理對象的消息封裝成遠程過程調用的COM/DCOM形式,通過TCP/IP發送到Windows環境里的COM組件。在最低的一層上,jCOM使用服務器上的標準Java網絡類進行調用。
圖1.jCOM運行時刻環境 點擊看原圖
三、使用jCOM工具
在實際開發中,除了使用WebLogic中的一些配置外,多數情況下還需要使用jCOM提供的工具程序。這些程序是jCOM的核心,在不同平臺間公開對象時,要用這些工具建立、部署所需要的元素。其中,常用的有:com2java、java2com、regjvm、regtlb等。篇幅所限,在此僅介紹后面示例中直接用到的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版本,也有命令行版本。可以在\bea\webloogic81\server\bin目錄下找到com2java.EXE(GUI版本)和com2javacmd.exe(命令行版本)。
【導讀】第一部分析了
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%\
列表1.BankAccount.jsp(在此僅列出主要代碼片斷)
<%! Private clsAccount account; %> |
二、建立后端帳戶COM組件
接下來,要建立后端的銀行賬戶COM組件。為了簡化,本示例假定和COM組件在同一臺計算機上運行并且選用Visual Basic 6.0來創建這里的銀行賬戶COM組件。
1.
啟動Visual Basic,新建一個ActiveX Dll項目。
2.
把項目名稱修改為Account,類名設置為clsAccount。
3.
在clsAccount類中建立如下代碼:
'定義全局變量 |
4.
單擊菜單“文件-項目另存為”,把項目保存在D:\myex\jCOM\Bank
5.
在文件菜單中,單擊“Make Account.dll”,建立組件的動態鏈接庫。
三、在服務器上安裝COM組件
在服務器上安裝COM需要好幾項操作。上面創建的COM組件要通過jCOM公開給Java客戶機,然后,Java對象即可以象調用其它Java類一樣調用這個COM組件。
1.
注冊組件
我這里試驗用的服務器為Windows
Regsvr32 Account.dll /s
2.
設置組件服務
在這個示例中,我們所用的操作系統是簡體中文Windows
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
4.
單擊“Generate Proxies”,選擇一個臨時目錄,保存程序生成的代理文件。
最后,com2java生成4個代理文件,用于在API一級訪問銀行賬戶COM組件之用。這4個代理文件分別是_clsAccount.java、_clsAccountProxy.java、clsAccount.java和JintegraInit.java。編譯這4個類,把它們放到WebLogic Server上示例應用程序能夠訪問到的目錄中。
所有與jCOM相關的、編譯時要使用的類,都保存在\bea\weblogic81\server\lib\weblogic.jar這個文件里。要確保在編譯時,在類路徑里引用這個JAR文件。
在WebLogic Server上,建立目錄結構\beaweblogic81\
四、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 Server的jCOM實現技術之后,通過一個具體實例來說明了jCOM的具體使用過程。
其實,Java/COM互操作是個相當復雜的主題,對市場上提供的各種方案的選用應視具體的環境而定。總之,如果想尋找一個穩定可靠的,而且無縫地在Java對象和微軟COM對象之間通信的機制的話,我建議優先考慮jCOM。