(by huihoo.org 趙晨希,zhaochenxi@vip.sina.com)
1.JBoss簡(jiǎn)介
JBoss是一個(gè)運(yùn)行EJB的J2EE應(yīng)用服務(wù)器。它是開(kāi)放源代碼的項(xiàng)目,遵循最新的J2EE規(guī)范。從JBoss項(xiàng)目開(kāi)始至今,它已經(jīng)從一個(gè)EJB容器發(fā)展成為一個(gè)基于的J2EE的一個(gè)web 操作系統(tǒng)(operating system for web),它體現(xiàn)了J2EE規(guī)范中最新的技術(shù),并且它還在the JavaWorld Editors' Choice 2002評(píng)選中獲得“最佳Java應(yīng)用服務(wù)器”大獎(jiǎng)。無(wú)論是學(xué)習(xí)還是應(yīng)用,JBoss為我們提供了一個(gè)非常優(yōu)秀的平臺(tái)。有關(guān)JBoss的詳細(xì)信息請(qǐng)參閱其主頁(yè)http://www.jboss.org。
剛開(kāi)始使用JBoss進(jìn)行EJB開(kāi)發(fā)時(shí),由于可供參考的資源不是很多,所以有一個(gè)比較困難的起步階段。JBoss的配置和使用沒(méi)有提供圖形向?qū)Ы缑妫蚤_(kāi)發(fā)部署EJB相對(duì)比較復(fù)雜。本文通過(guò)盡量具體的演示來(lái)對(duì)JBoss3.0下的EJB開(kāi)發(fā)和部署的進(jìn)行一個(gè)簡(jiǎn)單的介紹,從而使剛開(kāi)始使用JBoss的用戶可以很快地進(jìn)入到真正的J2EE應(yīng)用開(kāi)發(fā)中。
由于本文主要介紹JBoss3.0中不同類(lèi)型EJB的配置和部署,不對(duì)基本的EJB開(kāi)發(fā)做太多的描述,所以希望讀者具有J2EE和EJB的經(jīng)驗(yàn)。想要了解有關(guān)信息請(qǐng)查閱參考資料1。
2.JBoss3.0中基本的ejb配置和部署
根據(jù)J2EE規(guī)范的要求,一個(gè)基本的ejb jar包使用的描述文件是ejb-jar.xml。web應(yīng)用的war包使用的是web.xml。企業(yè)應(yīng)用的ear包使用的是application.xml。這些配置文件都是中性的和平臺(tái)無(wú)關(guān)的。同時(shí)應(yīng)用服務(wù)器可以使用一些其他的配置文件用于描述特定服務(wù)器的相關(guān)信息。在JBoss中這樣的文件有jboss.xml,jboss-web.xml等。JBoss容器中這些文件不是必須的,如果提供了那么jboss.xml和ejb-jar.xml放在同一目錄下,jboss-web.xml和web.xml放在同一目錄下。關(guān)于jboss.xml和jboss-web.xml的規(guī)范請(qǐng)參考JBoss安裝目錄下docs/dtd/目錄下的對(duì)應(yīng)的DTD文件。
2.1 JBoss中關(guān)于EJB客戶端的配置:
調(diào)用EJB的客戶端可以是JSP、Servlet或客戶端應(yīng)用程序。如果客戶端和服務(wù)器不在同一個(gè)Java VM上,那么在客戶端必須提供一個(gè)jndi.properties文件告訴客戶端進(jìn)行有關(guān)JNDI命名服務(wù)的信息,并且把這個(gè)文件所在目錄設(shè)定到環(huán)境變量classpath中。
以下是一個(gè)jndi.properties的樣例:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099 (服務(wù)器地址和端口號(hào))
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
通過(guò)這個(gè)文件和JBoss的一些客戶端類(lèi)庫(kù),就可以使用JBoss提供的EJB對(duì)象服務(wù)了。
2.2 JBoss中部署EJB:
首先介紹JBoss容器中部署各類(lèi)EJB對(duì)象的兩種方法。下面的演示以Session Bean為例,客戶端是一個(gè)本機(jī)上的web應(yīng)用。這里不對(duì)演示程序進(jìn)行具體介紹。
第一種方式:
把開(kāi)發(fā)好的ejb jar包和web應(yīng)用的war包公共放在deploy目錄下。
演示1:不需要jboss.xml文件和其他任何特殊的設(shè)置。
ejb-jar.xml:
<ejb-jar>
······
<ejb-name>ejbtest</ejb-name>
······
</ejb-jar>
客戶端:web應(yīng)用中對(duì)web.xml不需要添加ejb信息,不需要jboss-web.xml文件。引用ejb對(duì)象的jsp文件如下:
······
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("ejbtest"); //使用<ejb-name> beanHome=(zcxejb1Home)PortableRemoteObject.narrow(objref,ejbtestHome.class);
······
演示2:使用jboss.xml文件。
在缺省情況下JBoss的JNDI服務(wù)將通過(guò)ejb-jar.xml中<ejb-name>XXX</ejb-name>中的XXX來(lái)使用EJB的home interface。但是如果有多個(gè)ejb對(duì)象在相同的ejb jar包中,在ejb-jar.xml中通過(guò)<ejb-name>XXX</ejb-name>就可能不能很好的表示某一個(gè)ejb對(duì)象,所以一般我們希望可以提供一些附加的信息,例如采用這樣的格式"[應(yīng)用名]/[bean名]"來(lái)引用一個(gè)EJB對(duì)象。這時(shí)JNDI服務(wù)就可能不能正確地找到你的ejb對(duì)象,我們就需要使用jboss.xml文件,通過(guò)它實(shí)現(xiàn)jndi 名到ejb名的重定向。這個(gè)文件必須和ejb-jar.xml一起放到META-INFO目錄下。
ejb-jar.xml:
<ejb-jar>
······
<ejb-name>ejbtest</ejb-name>
······
</ejb-jar>
jboss.xml:
<jboss>
<ejb-name>ejbtest</ejb-name>
<jndi-name>example/ejbtest</jndi-name>
</jboss>
客戶端:需要使用新的jndi名進(jìn)行ejb定位。
······
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("example/ejbtest"); //使用<jndi-name> beanHome=(zcxejb1Home)PortableRemoteObject.narrow(objref,ejbtestHome.class);
······
第二種方式:
把ejb和web應(yīng)用包裝成一個(gè)企業(yè)應(yīng)用包。部署ear時(shí)可以簡(jiǎn)單地把通過(guò)application.xml描述ejb jar包和web應(yīng)用的war包,同樣在web.war中不需要提供特殊的信息就可以和第一種方式一樣使用ejb對(duì)象。客戶端代碼也不需要進(jìn)行改動(dòng)。這里不再舉例說(shuō)明。
此外我們可以進(jìn)行更進(jìn)一步的部署,這時(shí)需要使用到web.xml和jboss-web.xml。jboss-web.xml是JBoss提供的一個(gè)針對(duì)web應(yīng)用進(jìn)行配置的文件。jboss-web.xml和web.xml一起放在web應(yīng)用的WEB-INF目錄下。
演示1:改動(dòng)web.xml文件,添加<ejb-ref>標(biāo)記,不使用jboss-web.xml文件。
(注意<ejb-ref>包括內(nèi)部引用和外部引用。如果是同一個(gè)單元的可以通過(guò)<ejb-link>直接進(jìn)行引用,而不用提供其他信息。)
web.xml:
······
<ejb-ref>
<ejb-ref-name>ejb/ejbtest</ejb-ref-name> <!--采用sun推薦的命名方式-->
<ejb-ref-type>Session</ejb-ref-type>
<home>org.zcx.test.zcxejb1Home</home>
<remote>org.zcx.test.zcxejb1</remote>
<ejb-link>ejbtest</ejb-link> <!--必須和被應(yīng)用的ejb-name匹配-->
</ejb-ref>
······
客戶端:由于在web.xml中引入ejb引用描述這時(shí)ejb定位發(fā)生了變化:
······
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("java:comp/env/ ejb/ejbtest "); //使用java:comp/env命名空間 beanHome=(zcxejb1Home)PortableRemoteObject.narrow(objref,ejbtestHome.class);
······
演示2:聯(lián)合使用web.xml和jboss-web.xml
web.xml
······
<ejb-ref>
<ejb-ref-name>ejb/ejbtest</ejb-ref-name> <!--采用sun推薦的命名方式-->
<ejb-ref-type>Session</ejb-ref-type>
<home>org.zcx.test.zcxejb1Home</home>
<remote>org.zcx.test.zcxejb1</remote>
</ejb-ref>
······
jboss-web.xml
<ejb-ref>
<ejb-ref-name> ejb/ejbtest </ejb-ref-name>
<jndi-name> example/ejbtest </jndi-name> <!-- 這里對(duì)應(yīng)ejb對(duì)象的jndi名-->
</ejb-ref>
客戶端:
nitialContext ctx = new InitialContext();
Object objref = ctx.lookup("java:comp/env/ ejb/ejbtest "); beanHome=(zcxejb1Home)PortableRemoteObject.narrow(objref,ejbtestHome.class);
以上的所有演示說(shuō)明了ejb-jar.xml、jboss.xml、web.xml、jboss-web.xml之間的基本關(guān)系和它們的使用方式。它們是部署各類(lèi)ejb對(duì)象的關(guān)鍵文件。接下來(lái)介紹針對(duì)不同類(lèi)型的ejb對(duì)象所需要的特殊配置。
3.JBoss3.0中對(duì)于CMP2.0 Entity Bean的有關(guān)配置
JBoss3.0中JBossCMP引擎實(shí)現(xiàn)了EJB2.0 CMP2.0規(guī)范。JBoss3.0以前的版本CMP的引擎是Jaws,它通過(guò)standardjaws.xml和jaws.xml進(jìn)行有關(guān)的配置。在新的JBossCMP引擎中Jboss3.0通過(guò)standardjbosscmp-jdbc.xml和josscmp-jdbc.xml來(lái)配置Entity Bean。JBoss3.0首先處理standardjbosscmp-jdbc.xml然后根據(jù)ejb jar中是否提供jbosscmp-jdbc.xml來(lái)做進(jìn)一步處理。通過(guò)standardjbosscmp-jdbc.xml和jbosscmp-jdbc.xml可以為entity bean的部署提供如下的功能有:
l 指定所使用的數(shù)據(jù)源和對(duì)應(yīng)的類(lèi)型映射
l 指定一些引擎關(guān)心的屬性
l 指定引擎如何創(chuàng)建和管理數(shù)據(jù)庫(kù)表的原則
l 描述finder和ejbSelect方法
l 指定屬性和字段的類(lèi)型映射
這里主要根據(jù)standardjbosscmp-jdbc.xml/jbosscmp-jdbc.xml介紹CMP2.0的配置方法。JBoss中原有的Jaws引擎的配置方法和新的JBossCMP的配置方法類(lèi)似。這些文件的具體的信息可以參考JBoss安裝路徑下\docs\dtd中對(duì)應(yīng)的DTD文件。
3.1增加新的數(shù)據(jù)源
JBoss自帶的數(shù)據(jù)庫(kù)是Hypersonic數(shù)據(jù)庫(kù),我們可以增加一些新的數(shù)據(jù)源。具體的步驟很簡(jiǎn)單,參照Jboss安裝目錄下\docs\examples\jca中的*-service.xml文件可以增加找到對(duì)應(yīng)類(lèi)型的數(shù)據(jù)庫(kù)配置樣本文件。以mysql-service.xml文件為例,它可以配置一個(gè)MySQL數(shù)據(jù)庫(kù)作為Entity Bean的數(shù)據(jù)源。以下演示創(chuàng)建一個(gè)名為MySQLDS的MySQL數(shù)據(jù)源。
圖一是配置好的mysql-service.xml文件的一段代碼樣本,通過(guò)屬性設(shè)置可以定制數(shù)據(jù)源的名稱和有關(guān)連接的其他屬性。注意該文件中所有name屬性必須保持一致。
圖一 mysql-servic.xml的樣本代碼
在配置好這個(gè)文件后,把它部署在JBoss的deploy目錄下,把對(duì)應(yīng)的jdbc驅(qū)動(dòng)也放在lib目錄下。重新啟動(dòng)Jboss就會(huì)加載這個(gè)新的數(shù)據(jù)源。
3.2 Entity Bean 對(duì)數(shù)據(jù)源的使用
第一種方式:
直接改動(dòng)standardjbosscmp-jdbc.xml。把原有的數(shù)據(jù)源java:/DefautlDS屏蔽掉使用新的數(shù)據(jù)源java:/MySQLDS。(Java前綴是必須的。)不需在其他地方作改動(dòng)。JBoss會(huì)實(shí)現(xiàn)新的數(shù)據(jù)源做為缺省的數(shù)據(jù)源。圖二是一個(gè)配置好的文件片斷。
圖二 standardjbosscmp-jdbc.xml的樣本代碼
第二種方式:
由于有可能不同的Entity Bean使用不同的數(shù)據(jù)源,而不是都使用同樣的缺省配置,所以必須為單獨(dú)的Entity Bean提供定制數(shù)據(jù)源信息的支持。這時(shí)不需要改動(dòng)standardjbosscmp-jdbc.xml文件,可以通過(guò)在Entity Bean的jar包中META-INFO目錄下添加新的部署文件jbosscmp-jdbc.xml來(lái)完成。通過(guò)這個(gè)文件可以描述特定的Entity Bean的關(guān)于數(shù)據(jù)源的配置信息。圖三是一個(gè)配置好的文件片斷。
圖三 jbosscmp-jdbc.xml的樣本代碼
4.JBoss3.0中對(duì)于Message Driven Bean的配置
在JBoss中開(kāi)發(fā)MDB需要使用JMS功能。JMS是Sun公司開(kāi)發(fā)的面向消息的中間件API。它的主要目的是創(chuàng)造一種統(tǒng)一的面向消息編程的JavaAPI,從而避免使用提供商特定的API。現(xiàn)在有幾種不同的JMS系統(tǒng)可供使用。JBoss3.0中提供的是JBossMQ。
4.1 JBoss3.0中配置JMS服務(wù)
在JBoss3.0中與JMS服務(wù)相關(guān)的配置文件包括兩個(gè)文件:jbossMQ-service.xml和jbossMQ-destinations-service.xml。jbossMQ-service.xml配置了jbossMQ服務(wù)中的核心對(duì)象信息。一般我們不需要處理這個(gè)配置文件。jbossMQ-destinations-service.xml用于定義具體應(yīng)用所需的目的地信息。通過(guò)編輯它我們可以創(chuàng)建新的Topic和Queue用于具體的JMS應(yīng)用的目的地。在JBoss中創(chuàng)建應(yīng)用特定的Topic和Queues的步驟比較簡(jiǎn)單,參照jbossMQ-destinations-service.xml文件格式在該文件中添加自己應(yīng)用程序所需的Topic名為myTestAppTopic和Queue名為myTestAppQueue。如圖四所示。
圖四 jbossMQ-destinations-service.xml的樣本代碼
4.2 JBoss3.0中EJB使用JMS服務(wù)的配置
在開(kāi)發(fā)MDB 時(shí)要在部署文件中指定所使用的JMS服務(wù)中的目的地信息。JBoss中通過(guò)ejb-jar.xml和jboss.xml共同說(shuō)明。在jboss.xml中通過(guò)<destination-jndi-name>標(biāo)記描述所使用的目的地信息。
Ejb-jar.xml
<message-driven>
<ejb-name>HelloTopicMDB</ejb-name>
<ejb-class>org.zcx.test.HelloMDB</ejb-class>
<message-selector></message-selector>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<destination-type>javax.jms.Topic</destination-type>
<subscription-durability>NonDurable</subscription-durability>
</message-driven-destination>
</message-driven>
jboss.xml
<message-driven>
<ejb-name>HelloTopicMDB</ejb-name>
<configuration-name>Standard Message Driven Bean</configuration-name>
<destination-jndi-name>topic/myAppTestTopic</destination-jndi-name>
</message-driven>
客戶端:
······
Context context = new InitialContext();
// Get the connection factory
// Create the connection
// Create the session
······
// Look up the destination
topic = (Topic)context.lookup("topic/myTestAppTopic");
// Create a publisher
// Publish the message
······
5.JBoss3.0中EJB使用JavaMail服務(wù)的配置。
由于JBoss提供了JavaMail服務(wù)的實(shí)現(xiàn),所以在JBoss中使用JavaMail是非常方便地。它所需要配置的是mail.service文件。這個(gè)文件非常地簡(jiǎn)單不用多介紹。按照mail.service文件的的注釋就可以順利地完成配置。
圖五是使用JavaMail服務(wù)的一個(gè)sessionBean的代碼片斷
圖五 使用javamail的樣本代碼
以上通過(guò)例子簡(jiǎn)單的介紹了JBoss3.0中Session Bean、Entity Bean 和Message Drive Bean 最基本的配置和部署方法,通過(guò)這些介紹現(xiàn)在已經(jīng)可以在JBoss中進(jìn)行基本的EJB應(yīng)用的開(kāi)發(fā)了。本文中對(duì)于EJB應(yīng)用中比較復(fù)雜的一些配置像權(quán)限設(shè)置、資源管理和CMP2.0中的眾多配置等都沒(méi)有涉及到,希望大家可以在不斷的實(shí)踐和交流中更好地掌握JBoss的使用和配置。