一步一步教你用JCA
http://weli.iteye.com/blog/1566189
JCA在J2EE的世界中可能算是比較晦澀的一個領域了,比起大家經常接觸到的WebService,ORM,JMS等經常高調出現的J2EE領域的名詞,似乎JCA生存在最最陰暗的角落。實際上JCA並不難理解,而且可以說JCA是J2EE領域中最爲重要的一部分,是它將J2EE中各組件聯繫在了一起。本文希望能夠用更平實的語言和介紹方面來帶大家進入到JCA的世界,真正理解這項重要技術。
本文是上篇,我將在這篇文章中簡單介紹JCA的概念。在下篇當中,我在Red Hat北京研發中心的同事lgao會帶大家手把手在JBoss AS7中使用JCA開發一個示例項目。
什麼是J2EE
從文字角度上說,J2EE的全稱叫做Java Platform, Enterprise Edition。即Java企業版。另外,J2EE這個詞已經是過去式了,現在叫JavaEE。
從代碼角度上說,大多數JDK中包含的javax.*的包都屬於J2EE的範圍:
從理解的角度上來講,J2EE是Java提供給我們的一個超級龐大的類庫及接口規範,它包羅萬象:
* WebService
* 數據庫
* 消息中間件
* 事務管理
...
可以說,你在開發過程中想到遇到的問題,幾乎都能從J2EE中找到相關的規範與實現了這些規範的工具,比如我舉些例子:
* WebService下面有基於XML的JAX-WS規範,以及基於REST的JAX-RS規範。實現了這些規範的開源項目有:Apache CXF,RESTEasy等
* 數據庫有JPA規範,相關的開源工具當然是大名鼎鼎的Hibernate。
* 消息中間件有JMS規範,實現了這一規範的開源工具包括HornetQ,Apache ActiveMQ等等。
所以說,Java社區最大的特色可能就是各種J2EE規範及數量龐大的實現了這些規範的開源項目了,這是任何其它語言社區所不具備的一個特點。
之所以是這樣,有技術和非技術兩方面原因。在非技術層面,由於世界上最大的軟件公司Oracle,IBM及世界上最牛的開源公司Red Hat在用$$$大力砸進Java,造就了Java的繁榮。技術方面的原因,由於Java本身良好的語言特性,優秀的性能以及穩定的虛擬機技術,使得Java成爲天然的構建商業應用的語言。
最終,一切這些既成事實,造就了Java社區今天的樣貌。
在J2EE的世界當中,這許許多多的規範和技術裏面,可能大家會覺得有難有易,有深有淺。比如在開發項目中經要常用到的Hibernate及其實現的JPA規範,由於用的人多,文檔多,再加上天天用,和數據庫打交道基本都用它,所以可能會覺得相對比較簡單。
至於本文中要介紹的JCA這個J2EE的家庭成員,可能對很多人來講就覺得很陌生,因爲平時可能用到不多,文檔少,涉及到的概念比較晦澀,所以感覺上很難。
其實JCA並不難,並且用處很大,雖然可能你不直接用到它,但可能你已經在日常開發過程中使用到了它。假如你用JBoss AS服務器或者是WebShpere服務器來部署你的項目,那麼你已經在使用JCA技術了。
因此本文的目的是在概念上讓你對JCA有一個熟悉,讓它變得不那麼陌生。
什麼是JCA?
JCA的全稱是J2EE Connector Architecture,它定義了一個連接J2EE平臺和Enterprise Information Systems(EIS)的標準架構,使得各個EIS能夠接入到Application Server當中。
好吧,如果你現在並不瞭解JCA,那麼上面的定義基本上是天書。彆着急,下面開始進行詳細的講解:
什麼是EIS?
EIS,全稱: Enterprise Information System, 是一個虛的概念,用簡單明瞭的話來講,就是你現有的系統資源。比如你現在在一個企業裏面,這個企業原來開發了幾個項目,分別是A,B,C。A是一個Web項目,用Servlet開發的;B是一個FTP服務器,上面有些文件;C是一個數據庫,裏面有點數據。那麼,A,B,C都叫EIS。總之就是你現有的雜七雜八的一些IT資源。常見的 EIS 多爲: Database, ERP, SAP 等。大家經常用到的 JBoss 下 DataSource 管理就是
JCA 的一個典型應用。
什麼是J2EE Application Server?
J2EE Application Server就是支持各種(最好是所有)J2EE技術的應用服務器。比如開源的JBoss AS,或者是WebSphere,這些都是J2EE Application Server。因爲它們支持各種J2EE的標準和框架。
比如你做了個和數據庫有關的項目,是基於JPA接口規範做的,那麼你既可以把它部署在JBoss AS裏面,用Hibernate支持跑起來你的項目,也可以部署在WebSphere服務器裏面,使用另一套解決方案。
因此,這些實現了J2EE各個規範的服務器,就叫做J2EE Application Server。
那麼Tomcat算不算J2EE Application Server呢?
嚴格來講,Tomcat不能算是J2EE Application Server,它只能說是一個Servlet容器,雖然Servlet標準也是J2EE世界中的一員。
Tomcat支持的J2EE組件太少了,它不包含對J2EE的事務標準JTA的支持,也不支持JMS,不支持JPA(沒有Hibernate這樣的組件),不支持EJB,不支持各種WebSerivce。。。
當然,你可以在Tomcat的基礎上打造一個準J2EE Application Server。比如,你可以在自己的項目裏面加上Hibernate,加上ActiveMQ,加上WebService,加上OpenEJB。。。
但是到最後,你會發現這樣做的結果是花了大量的時間在搭建環境上面,並且最後弄出來的東西其實也並不是J2EE Application Server。因爲它缺少一些最最核心的東西:
* 分佈式事務處理能力
* 羣集解決方案
* 接入企業現有IT資源
因此,一般使用Tomcat的項目,都不太會考慮用J2EE技術來進行技術架構,而採用一些更爲輕的解決方案,比如Springframwork + Hibernate + Struts等等。然後再通過後期一些別的技術來考慮羣集和可擴展的問題。那是另一種技術方向,在初期比較輕快,開發週期短等優勢,當然也有它的侷限,面向不同規模和不同性質的應用。
什麼是JCA?(again)
在理解了上面一大堆概念以後,我們現在要再次回到這個問題上面:
* 什麼是JCA?
我們再來重複一開始給出的定義,稍微簡化一下:
_JCA就是把你的EIS接進你的Application Server,同時讓其它的J2EE組件可以訪問到你的EIS。_
什麼是接入?
在JCA的定義中,接入這個概念比較模糊,到底什麼是接入?對於EIS資源來講,用戶日常的使用不就是接入了嗎?比如:我們有一個FTP服務器,用戶每天在下載文件;我們還有一個HTTP服務器,上面跑着一些Web服務,用戶在用。那麼爲什麼還需要“接入”呢?
是的,對於用戶來講,獨立的使用這些IT資源,也是可以的。但是對於一個企業來講,它可能有很多的歷史積累,需要把這些歷史積累下來形成的資源整合到一個統一的平臺上面去,形成一個完整的項目,提供給用戶去使用。
這樣的整合,往往並不是簡單的已有的東西拼湊在一起,可能要在已有系統的基礎上面做改造,然後將它們統一整合起來,形成完整的一個系統。這裏面有很多要考慮的東西,既包括代碼開發層面,也包括部署層面,因此是一個相當複雜的系統工程,每家企業可能有各自的解決方法。其結果,有成功,也有失敗。
在J2EE的世界中,爲了解決這一問題,Java標準委員會(JCP, http://jcp.org/en/home/index)制定了JCA標準,專門用於將這些系統資源(EIS)接入到J2EE的Application Server當中。比如一些使用場景:
* 我如何將我已有的FTP服務器接到JBoss AS中?
* 我如何將我的數據庫資源接到WebShpere裏?
* 我原來自己開發了一個代碼框架,我可不可以在JBoss EAP的環境中繼續使用我的這些代碼並且保證它和其它使用了EJB,WebService,JMS技術的一些JBoss EAP中開發的項目整合在一起?
* 我有一個已有的系統,一個數據庫,一個Web服務,我可不可以讓它們幾個在JBoss AS中運行時,有統一的事務管理?
如果沒有JCA標準,可能上面這些問題並不好回答,甚至於根本就沒有標準答案。但是有了JCA標準,讓EIS的接入,有了統一的規範可以遵守,過去的經驗可以利用,資源可以被積累。在JCA標準中,最重要的就是它定義了“接入”的概念。也就是說,JCA標準告訴了你,什麼的情況下,一個系統叫做“接入”了應用服務器。
總的來講,JCA把要接入的叫做Contract(合約)。JCA定義了三個Contract:
* Connection management (連接管理)
* Transaction management (事務管理)
* Security (安全規範)
連接管理
在連接管理當中,J2EE 應用服務器提供連接池的管理。 部署在 J2EE 應用服務器裏的RAR(什麼是RAR?這裏賣個關子,文章最後一節中會講解)按照規範要求,提供打開連接方法,關閉連接方法等等,讓J2EE的應用服務器可以方便的訪問EIS。
事務管理
同理,事務管理規範要求待接入的EIS要提供相關的事務功能,這樣,當EIS資源參與J2EE的應用服務器的整體業務時,可以參與到整體的事務中來。
事務管理定義了本地事務和分佈式事務兩方面的接口規範。
安全規範
在安全規範中,定義了EIS要如何參與整體系統的統一認證過程。
小結
通過規範以上三個層面,JCA標準告訴了你該如何將EIS接入J2EE的應用服務器,從而形成一個整體。另外,我們需要注意:
* 並不是所有的EIS在接入時都需要實現上面三個contract,根據自己的需要,接入必須的部分就可以了。比如FTP服務器,我們可能並不需要接入事務管理。
* 不要將EIS誤解爲只能是以前舊有的系統。實際上在J2EE的應用服務器中,很多組件都是通過JCA的架構規範被集成在一起的。比如JBoss AS中的HornetQ,Hibernate等很多組件都是通過JCA規範與JBoss AS服務器集成在一起的。
接下來,我們來看看這張圖:
圖片來源 -
http://java.sun.com/j2ee/white/images/image9.gif
細心的讀者可能注意到在System Contracts和EIS之間有個ResourceAdaper,這是什麼呢?接着往下看:
什麼是ResourceAdapter?
從圖中可以看出ResourceAdapter就是實現上述這些Contracts的實際組件了,我們要使用JCA的話,主要的工作就是實現ResourceAdpater中的各個接口,調用EIS中的資源,將EIS接入到應用服務器當中。因此,代碼的工作在這裏。
實現好的ResourceAdapter項目,將打包成RAR形成,部署到應用服務器當中,用於和EIS交互。我們知道,常用的Java項目封裝方式包括:RAR,WAR,EAR。。。而RAR就是JCA要求的項目封裝形式了。
下面再來一張圖幫助理解:
http://java.sun.com/developer/technicalArticles/J2EE/connectorclient/resourceadapter_fig2.gif
有關ResourceAdpater的撰寫和具體的接口規範等,將在本文的下篇中,由我的同事lgao爲大家講解,本文中不詳細展開。
參考資料
Connect the enterprise with the JCA -
http://www.javaworld.com/javaworld/jw-11-2001/jw-1121-jca.html
Introduction to the J2EE Connector Architecture -
http://www.ibm.com/developerworks/java/tutorials/j-jca/
Use cases for JCA -
http://stackoverflow.com/questions/4157776/use-cases-for-jca
Choosing among JCA, JMS, and web services for EAI -
http://www.ibm.com/developerworks/webservices/library/ws-jcajms/index.html
Java Platform, Enterprise Edition -
http://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition
The J2EE Connector Architecture's Resource -
http://java.sun.com/developer/technicalArticles/J2EE/connectorclient/resourceadapter.html
http://weli.iteye.com/blog/1591180
在本文中我們要用到的EIS是一個Servlet的服務,運行在一個JBoss AS服務器上(實際上運行在哪裏無所謂,是什麼也不重要。因爲JCA標準中,並沒有對EIS的形式或內容做要求。可以是文件,數據庫,FTP服務,或像本文要用到的這個HTTP Servlet服務)。
這個項目的功能是列出自己電腦上的目錄。我們將這個項目命名爲:
* services-1.0.0.war
然後我們要使用另一臺JBoss AS服務器做爲Application Server,在這上面開發一個ResourceAdapter,用RAR的形式部署,將EIS接進來。將這個項目命名爲:
* listfiles-0.1.rar
最後,我們要在Application Server上面開發一個Web應用,使用這個ResourceAdapter爲我們接入的EIS資源,提供給最終用戶進行使用。這個項目名爲:
* listfiles-0.1.war
示例的整體架構圖如下:
接下來是實施過程:
製作EIS
在一般的JCA開發過程中,應該是沒有這步的,因爲我們是要將已有的EIS通過ResourceAdpator接進Application Server。但是因爲這個例子要爲大家展示完整的過程,因此我們要首先動手製作一個EIS。
首先使用maven[1]創建一個webapp:
我們要做一個Servlet,這個Servlet的功能很簡單:用戶給出一個dir目錄,Servlet列出這個目錄中的文件,就相當於ls命令:
這就是這個EIS的全部功能了,接下來將項目打包:
生成services-1.0.0.war,然後我們將它部署到JBoss AS服務器上,這個項目就算弄完了。
製作ResourceAdapter
接下來我們要製作核心部分ResourceAdapter。在這裏,我們要用到JBoss社區的JCA標準實現框架IronJacamar[2]。
IronJacamar下載完成後,切換到:
運行:
按照提示輸入:
在上述提示中, 紅色下劃線標記的爲輸入,其他因爲採用提示給的默認值,因此直接回車就可以。其中:
這個配置指向你的EIS所在機器的IP地址。此外注意到我們設置中的Transaction Support和Re-authenticatiion都是No。也就是說,我們不準備在這個ResourceAdapter中實現事務管理contract和認證contract。是一個相當簡單的ResourceAdapter。
完成後,會在當前目錄下產生一個叫做out的目錄,並生成了一系列的Java代碼,下面是out目錄結構:
我們看一下相應的類圖:
* 在JCA規範中,暴露給用戶的連接管理接口是ConnectionFactory。在本例當中我們的ConnectionFactory爲ListFilesConnectionFactory。
* 通過ListFilesConnectionFactory.getConnection()獲取到ListFilesConnection實例。
* ListFilesConnection 實例通過 ListFilesManagedConnection與相應的EIS 交互。
* ListFilesMangedConnection代表和EIS的物理連接;ListFilesConnection是這個物理連接的Handler。
首先我們實現ListFilesConnection接口,定義一個方法:
然後在ListFilesConnectionImpl中實現它:
注意到ListFilesManagedConnection是實際要實現這個方法的地方,因此,接下來我們要在ListFilesManagedConnection中實現與EIS實際交互的邏輯。因爲我們的EIS是一個Servlet的Web服務,因此通過網絡調用它,並獲取返回值,實現EIS的接入:
Java代碼挺簡單的,接下來我們要編輯IronJacamar的配置文件:
下面是配置的詳細內容,很容易理解:
ResourceAdapter的全部代碼工作至此完成了,接下來將項目打包:
生成listfiles-0.1.rar,這個就是我們需要的RAR文件了。將這個文件部署到Application Server當中。
創建客戶端
有了EIS,也有了ResourceAdapter來接入這個EIS,接下來我們要寫一個客戶端應用,來通過ResourceAdapter使用這個EIS。請注意這裏面說的客戶端並不是最終用戶,而是通過ResouceAdapter來使用EIS的應用,我們稱其爲客戶端。
還是使用mvn來創建一個Web項目:
僅需要撰寫一個jsp文件,打開:
內容如下:
功能很簡單:給用戶一個輸入表單->輸入需要顯示的目錄->將用戶的請求提交給ResourceAdapter->ResourceAdapter去調用EIS並返回結果。
雖然功能不難,但是代碼當中包含了很多ResourceAdapter的調用方法:
接下來我們需要編輯一下:
這個文件,因爲在JBoss AS 7中, 要求這個文件中包含項目所依賴的ResourceAdapter信息,格式如下:
因此我們在這個文件中添加內容如下:
指定這個客戶端項目依賴於listfiles-0.1.rar。最後還是項目打包:
生成listfileweb-1.0.0.war。
部署
至此爲止,我們應該有了三樣東西:
* services.war - EIS
* listfileweb-1.0.0.rar - RAR
* listfileweb-1.0.0.war - Client
我們要部署這些組件:
將listfileweb-1.0.0.rar和listfileweb-1.0.0.war部署在機器A的JBoss AS上面
假設 JBoss AS 7 的目錄在 ~/softwares/jboss-as/jboss-as-7.1.1.Final/, 那麼我們運行命令:
運行完以上指令, JBoss AS 7 就會啓動, 之後我們來部署 listfiles RAR 和 listfileweb WAR,打開另外一個控制檯,然後輸入:
如果兩條指令沒有錯誤提示, 部署就成功了。 我們可以確認下:
將services.war部署在機器B的JBoss AS上面
部署services.war的方法沒什麼不同,不再贅述。但是這臺機器上面的JBoss AS7的配置要稍做改變,因爲我們需要讓機器A中的ResourceAdapter能訪問到這臺機器上面的EIS資源,而AS7默認只偵聽localhost,所以要做出配置修改。打開:
修改:
爲:
然後啓動AS7服務器:
測試
萬事俱備,接下來進行測試。在機器A上面訪問Client:
效果如下:
在輸入框裏寫上要查看的目錄文件列表,此時RAR會調用EIS,返回EIS所在的機器B中的目錄內容:
以上,我們就完成了這個例子全部內容的展示。
小結
本文通過一個例子向大家展示JCA中ResourceAdapter的開發過程,以及對它的使用方式。雖然這個例子非常簡單,僅實現了JCA標準中提供的三個contracts中的最基本的Connection Management,但是它的流程是完整的,在此基礎上,你可以繼續深入閱讀JCA的相關資料,進一步學習它,也可以爲閱讀現有EIS的ResouceAdapter的源代碼打下良好基礎。相信這會是一個好的起點。
代碼
本文中用到的三個代碼我放在了github上面,有興趣可以遷出:
EIS
RAR
Client
文中用到的工具
Maven
Maven 是項目管理的工具, 可以很方便的進行項目的編譯,打包,測試。可以從以下網址找到下載連接。
筆者使用的 maven 版本是:
IronJacamar
IronJacamar 是 JBoss 的 JCA 1.6 實現,它提供了生成 JCA 代碼的工具和 standalone 的環境用來測試,從以下地址下載 IronJacamar:
本文使用的IronJacamar版本爲1.0.10.Final。
JBoss AS 7
我們在這個例子中使用JBoss AS 7做爲應用服務器還有EIS的例子工具。下面是網址:
筆者使用的 JBoss AS 7 版本是: 7.1.1.Final。
參考資料
JSR 322: JavaTM EE Connector Architecture 1.6 -
http://jcp.org/en/jsr/detail?id=322
IronJacamar 1.0 User's Guide -
http://docs.jboss.org/ironjacamar/userguide/1.0/en-US/html_single/
IronJacamar 1.0 Developer's Guide -
http://docs.jboss.org/ironjacamar/developerguide/1.0/en-US/html_single/