JBoss技術支持文檔
1、本節內容簡介本章主要介紹JBOSS(免費的 EJB服務器),以及教會大家如何安裝Jboss,建立你第一個EJB和客戶端。關于什么是EJB,以及如何開發等。這些關于EJB方面有很多書籍進行描 述,在此不再闡述。描述信息是運行在windows平臺,當然你可以應用在其他支持的平臺(如:Linux等)。
2、關于JBOSS
Jboss支持EJB 1.1和EJB 2.0的規范,它是一個為管理EJB的容器和服務器。類似于Sun’s J2SDK Enterprise Edition(J2EE),但是Jboss核心服務僅是提供EJB服務器。JBOSS不包括serverlers/JSP page 的WEB容器,當然可以和Tomcat或Jetty綁定使用。JBOSS需要比較小的內存和硬盤空間。可以在64M內存以及幾兆空間上很好的運行。而 Sun’s J2EE需要最少內存為128M,以及31M硬盤空間。JBOSS啟動速度要比J2EE快10倍。而且它能內嵌SQL 數據庫服務器進行持久性BEAN處理,當啟動時會自動啟動。(J2EE裝載分離CloudScape SQL Server)。
其中 一個非常好的特性JBOSS能夠“熱”部署,“熱”部署的意思就是在部署BEAN只是簡單拷貝BEAN的JAR文件到部署路徑下,如果BEAN已經被 LOAD,JBOSS卸載它,然后LOAD一個新版本BEAN。如果你需要更多的JBOSS特性,你可以查看關于JBOSS論壇的網站。如果需要支持,可 以付費聯系JBossGroup LLC。
本章一步一步幫助你開始用jboss進行分布式開發:如何建立一個簡單的BEAN,以及如何在jboss服務器上部署和在測試。
3、必備條件
JBOSS是一個純JAVA編寫的,需要一個JAVA系統和JDK1.3兼容。為了能便宜和運行所有的例子,你需要有Ant 1.4或以上版本。在下節將會介紹如何獲得和安裝。當然你要有開發EJB基礎。
4、安裝ANT
我們在很多書上以及網頁可能都看見過這個名字,到底它用來作什么的呢?Ant 是一個基于java的build工具。現在已經有了許多的build工具,例如make、gnumake、nmake、jam等,而且這些工具都非常優 秀。Ant是一個跨平臺的Build工具。之所以Ant能跨平臺,是因為Ant不再需要你編寫shell命令,Ant的配置文件是基于XML的任務樹,能 讓你運行各種各樣的任務,任務的運行是由實現了特定任務接口的對象來完成的。
有兩個版本Binary和Source 可以下載最新版本1.5.2。
Binary版: http://ant.apache.org/old-releases/v1.5.2/binaries/
Source版:http://ant.apache.org/old-releases/v1.5.2/source/
關于這兩個版本的不同之處可以參考http://ant.apache.org/ 。如果下載不了可以向我索取QQ:182244794, Email: amaryllis@163.net 。
在下載完Ant后,你解壓文件,全部文件會放在一個apache-ant-1.5.2路徑下。Ant文檔會釋放在docs/manual目錄下,你可以 打開網頁docs/manual/index.html來瀏覽關于ant文檔的內容。 我用Windows系統釋放在c:/apache-ant-1.5.2路徑下。
1) 設置ANT_HOME環境變量,指向你的ANT目錄。
2) 需要設置JAVA_HOME環境變量,指向你的JDK目錄。
3) 將%ANT_HOME%in加入到PATH環境變量中。
4) 當你不帶任何參數運行ant時,Ant會在當前目錄找一個名叫build.xml的文件。如果沒找到,會有以下提示:
Buildfile : build.xml does not exist!Build failed
為了測試ANT安裝是否成功,我建立了一個新的build.xml文件,放在當前的目錄下%ANT_HOME%samples。Build.xml內容如下:
<!-- Simple Ant build script to test an Ant installation --><br />
<project name="TestInstall" default="run" basedir="."><br />
<target name="init"> <br />
<available file="ASimpleHelloObject.java" property="ASimpleHelloObject"/> <br />
</target> <br />
<target name="ASimpleHelloObject" unless="ASimpleHelloObject" depends="init"> <br />
<echo file="ASimpleHelloObject.java"><br />
public class ASimpleHelloObject<br />
{<br />
public static void main(String[] args) { <br />
System.out.println("ASimpleHelloObject.main was called"); }<br />
}<br />
</echo> <br />
<echo message="Wrote ASimpleHelloObject.java" /> <br />
</target> <br />
<target name="compile" depends="ASimpleHelloObject"> <br />
<javac destdir="." srcdir="." debug="on" classpath="."> <br />
<include name="ASimpleHelloObject.java"/> <br />
</javac> <br />
</target> <br />
<target name="run" depends="compile"> <br />
<java classname="ASimpleHelloObject" classpath="." /> <br />
<echo message="Ant appears to be successfully installed" /> <br />
</target><br />
</project><br />
運行ant 顯示結果如下:
c:apache-ant-1.5.2samples> antBuildfile: build.xml
Init :
AsimpleHelloObject:
[echo] Wrote AsimpleHelloObject.java
compile:
[javac] Compiling 1 source file to c:apache-ant-1.5.2samples
run :
[java] AsimpleHelloObject.main was called[echo] Ant appears to be successfully installed
BUILDE SUCCESSFUL
Total time :11 seconds.
到此你安裝的ANT以及環境已經設置成功。如果有以下警告
Warning: JAVA_HOME environment variable is not set. If build fails because sun.* classes could not be found you will need to set the JAVA_HOME environment variable to the installation directory of java.
表示你需要設置JAVA_HOME環境,指定你安裝的JDK 目錄。如何運用Ant 中的各種命令,我會在以后編寫《ANT文檔》介紹。
5、安裝JBOSS
1) 在安裝和運行JBoss 之前,你必須檢查是否安裝了JDK,需要在PATH環境中,設置JDK的目錄。
2)、 下載JBoss 服務器。JBoss 是一個壓縮文件,你可以下載最新版本。為了能支持Web Server,我用的是Windows平臺,所以下載了jboss3.0.6-tomcat4.1.18。你可以到http: //prdownloads.sourceforge.net/jboss/ 中直接下載。如果你使用的是Unix/Lunix平臺也可以從這個網址下載相應的JBoss 服務器。
3)、安裝
(1) Lunix/Unix下安裝
a、 你下載了對于Unix/Lunix版本的JBoss 服務器l 用JDK 的JAR工具來解壓文件到一個臨時目錄。
b、 設置JBOSS_DIST指向JBoss 解壓后最頂級目錄。
c、 然后到此目錄下
cd JBOSS_DIST/bin
sh run.shl
運行完后顯示信息如下:
bash-2.04$ /bin/sh run.sh
JBOSS_CLASSPATH=:run.jar:../lib/crimson.jar
jboss.home = /tmp/JBoss-2.2.2
Using JAAS LoginConfig: file:/tmp/JBoss-2.2.2/conf/default/auth.conf
Using configuration "default"
[Info] Java version: 1.3.1,Sun Microsystems Inc.
[Info] Java VM: Java HotSpot(TM) Server VM 1.3.1-b24,Sun Microsystems Inc.
[Info] System: Linux 2.2.16-22,i386
[Shutdown] Shutdown hook added
[Service Control] Registered with server
[Service Control] Initializing 24 MBeans
...
[Service Control] Started 24 services
[Default] JBoss 2.2.2 Started in 0m:7s
(2) Windows下安裝
a、 下載jboss3.0.6-tomcat4.1.18.zip, 然后用winzip解壓到一個目錄,我解壓在c:jboss3.0.6-tomcat4.1.18目錄
b、 解壓后基本上不需要配置,運用bin目錄下的run.bat命令。
c、 運行run.bat命令,請看后臺有沒有什么異常拋出。
d、 運行成功請訪問http://localhost:8083將會出現空白頁。訪問http://localhost:8080將會出現Tomcat的歡迎 頁面,如果出現Apache Tomcat/4.1.12 - HTTP Status 500 - No Context configured to process this request的錯誤,這是正常的,因為你還沒有發布.ear或.war應用。當然jboss-3.2.ORC3_tomcat-4.1.18.zip不 會出現這樣的問題,因為在目錄serverdefaultdeploy中自帶了web測試文件webtest.ear 訪問http://localhost:8082你可以看到Jboss起動的服務。你可以運行http://localhost:8080/jmx- console就會出現相關頁面。
(3) Window NT 和2000補充
對于NT和Win2k系統如果你要安裝NT或Win2k服務的話,可以把jboss加在系統服務中,避免你每次需要到jboss目錄下運行run.bat命令,只是當系統啟動時,自動啟動jboss服務器。
a、 首先你需要下載javaservice.exe文件。l 編輯一個批處理文件,自己命名文件名,存入和JavaService.exe相同的目錄。我命名為Jboss_Tomcat_Service.bat此文 件的內容@echo offecho --------
echo Usage: %0 jdk_home tomcat_home (classic/hotspot/server)echo NOTE: You MAY NOT use spaces in the path names. If you know howecho to fix this, please tell me.echo JDK 1.4 does not come with hotpot server by default, you mustecho install this seperately if you wish to use it.echo Example: %0 ..jdk ..jboss30 hotspot
echo --------
if "%1" == "uninstall" goto uninstall
if "%1" == "-uninstall" goto uninstall
if "%1" == "" goto usage
if "%2" == "" goto usage
if "%3" == "" goto usage
if "%1" == "-help" goto usage
if "%1" == "-?" goto usage
if "%1" == "/?" goto usage
:install
JavaService.exe -install JBoss306 %1jrein%3jvm.dll -Djava.class.path=%1lib ools.jar;%2in un.jar -start org.jboss.Main -stop org.jboss.Main -method systemExit -out %2inout.txt -current %2in goto eof
:uninstall
JavaService.exe -uninstall JBoss306
goto eof
:usage
echo -------- To Install JBoss 3.0.6 do
echo Usage: %0 jdk_home jboss_home (classic/hotspot/server)
echo NOTE: You MAY NOT use spaces in the path names. If you know how echo to fix this, please tell me.
echo JDK 1.4 does not come with hotpot server by default, you must echo install this seperately if you wish to use it.
echo Example: %0 ..jdk ..jboss30 hotspot
echo --------
echo -------- To Uninstall JBoss 3.0.6 do
echo Usage: %0 uninstall echo --------
goto eof
:eof
e、 運行以下命令
Jboss_Tomcat_Service C:j2sdk1.4.0_02 C:jboss-3.0.6_tomcat-4.1.18 server
其中C:j2sdk1.4.0_02是java安裝的目錄 C:jboss-3.0.6_tomcat-4.1.18是Jboss安裝的目錄,server是不變的參數
f、將會看到安裝成功的命令,你到win2k或NT的Service中看我可以看Jboss306的服務,你可以正常的起動它。然后再查看各種網頁(同windows安裝相同)如果成功,到此恭喜你,你安裝了JBoss服務器。
(4)問題
如果在在安裝了服務,網頁顯示不正確。你需要多試幾次,首先運行
Jboss_Tomcat_Service uninstall
然后再運行
Jboss_Tomcat_Service C:j2sdk1.4.0_02 C:jboss-3.0.6_tomcat-4.1.18 server。
1、下載例子源程序
所有例子的源代碼可以直接從 www.jboss.org進行下載。下載完后放在一個目錄下。下載網址:http://www.jboss.org/docs/manual/files/documentation-example.zip
1.1 建立 BEAN
此節主要是建立一個簡單的EJB,可以查看代碼,這個“Interest”例子,是一個簡單無狀態的會話EJB。它的目的是根據說明的利息率,來對借的所有錢計算利息。實際上在整個包代碼中只有一行功能。
1.2 回顧EJBs
在我們查看代碼之前,我們先對EJB進行復習一下。在EJB最小類型,也必須有三個類:remote interface, home interface和bean實現類。
remote interface是會把EJB中方法提供給外邊世界,讓外邊的代碼來進行調用,在這個例子中類名稱是org.jboss.interest.Interrest。
home interface是管理remote interface類的類。包括建立、刪除等操作。在這個例子中類名稱是org.jboss.interest.InterrestHome。
bean實現類提供home interface和remote interface所有方法的實現。在這個例子中類名稱是org.jboss.interest.InterrestBean。
當然一個Bean可能還包括其他類,甚至其他包。但是必須有此三個類,其他類是在此三個類之上建立的。所有類被打包進一個JAR文件,此文件是用一個目 錄結構來反映出包的層次關系。在此例子中所有類都打包在org.jboss.interest包中,所以他們需要在目錄 org/jboss/interest/下。
在包含所有類的jar文件建立之前,必須有一個META-INF目錄。此目錄存放了部署描述符(通常叫“ejb-jar.xml”),和可選的其他XML文件。這些文件告訴服務器關于應用明確服務信息。對于JBoss 來講,文件名必須叫“jboss.xml”。
創建jar文件后部署到JBoss Server上。在客戶端你需要一個jndi.properties文件,此文件告訴你的客戶端程序從哪里初始化查找JNDI 命名服務。從這個服務,客戶端將查找到Interest bean,并且返回bean的home interface。home interface用來得到bean的一個remote interface。它可以用遠程接口來訪問bean提供的商業方法。
1.3 EJB類
我們需要三個類:remote interface, home interface 和bean實現類。remote interface遠程接口類,文件名Interest.java。代碼如下:
package org.jboss.docs.interest;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
/**
This interface defines the `Remote´ interface for the `Interest´ EJB. Its
single method is the only method exposed to the outside world. The class
InterestBean implements the method.
*/
public interface Interest extends EJBObject
{
/** Calulates the compound interest on the sum `principle´, with interest rate per period `rate´ over `periods´ time periods. This method also prints a message to standard output; this is picked up by the EJB server and logged. In this way we can demonstrate that the method is actually being executed on the server, rather than the client. */
public double calculateCompoundInterest(double principle, double rate, double periods) throws RemoteException;
}
遠程接口只有一個商業方法calculateCompoundInterest。Home interface 文件名InterestHome.java。代碼如下:
package org.jboss.docs.interest;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
This interface defines the ´home´ interface for the ´Interest´ EJB.
*/
public interface InterestHome extends EJBHome
{
/** Creates an instance of the `InterestBean´ class on the server, and returns a remote reference to an Interest interface on the client. */
Interest create() throws RemoteException, CreateException;
}
最后我們給出bean實現類,文件名稱:InterestBean.java。代碼如下:
package org.jboss.docs.interest;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
/**
This class contains the implementation for the ´calculateCompoundInterest´ method exposed by this Bean. It includes empty method bodies for the methods prescribe by the SessionBean interface; these don´t need to do anything in this simple example. */public class InterestBean implements SessionBean
{
/** Calulates the compound interest on the sum `principle´, with interest rate per period `rate´ over `periods´ time periods. This method also prints a message to standard output; this is picked up by the EJB server and logged. In this way we can demonstrate that the method is actually being executed on the server, rather than the client. */
public double calculateCompoundInterest(double principle, double rate, double periods)
{
System.out.println("Someone called `calculateCompoundInterest!´");
return principle * Math.pow(1+rate, periods) - principle;
}
/** Empty method body */
public void ejbCreate() {}
/** Every ejbCreate() method ALWAYS needs a corresponding ejbPostCreate() method with exactly the same parameter types. */
public void ejbPostCreate() {}
/** Empty method body */
public void ejbRemove() {} /** Empty method body */
public void ejbActivate() {} /** Empty method body */
public void ejbPassivate() {} /** Empty method body */
public void setSessionContext(SessionContext sc) {}
}
注意大部分方法是空的。因為這些方法在SessionBean接口中說明,所以必須在InterestBean中存在,但在這個簡單例子中,不需要具體內容。
2、部署描述符
當你編輯完類文件后,我們來看部署描述符。此文件告訴EJB Server是哪個類應該被喚醒bean、Home Interface 和remote Interface。如果一個包中有不止一個bean,它指明ejb同另外bean如何相和。在這
個簡單例子中只有一個ejb,所以我們不用關心這方面問題。
大部分商業EJB Server都提供圖形化部署工具,來構造部署描述符,JBoss沒有XML編輯器,但是它能夠簡單手工構造部署描述符。下面是Interest Bean部署描述符:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar>
<description>JBoss Interest Sample Application</description>
<display-name>Interest EJB</display-name>
<enterprise-beans>
<session>
<ejb-name>Interest</ejb-name>
<home>org.jboss.docs.interest.InterestHome</home>
<remote>org.jboss.docs.interest.Interest</remote>
<ejb-class>org.jboss.docs.interest.InterestBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
部署描述符文件必須命名為“ejb-jar.xml”,并且必須放在目錄META-INF下。一個大家容易犯的錯誤是目錄名字,有的寫成“META_INF”, “META~INF”或“meta-inf”所有這些都不能正常的工作。
我們在server上部署一個應用程序,而不是一個ejb。在這個例子中我們的應用程序只有一個ejb。在部署描述符中<ejb-name> Interest</ejb-name>表明ejb的名稱。JBoss缺省是把bean的home interface作為JNDI命名空間放在<ejb-name>中,除非你修改缺省值。實際上客戶端應用程序不是必須使用這個名字的。開發者不用為 JNDI命名空間指明一個不同的名字而費心。然而一個由完整應用程序的產品包含多個beans,通常用一個和開發者說明不同的名字。所以會發現 “[application name]/[bean name]”等,關于這部分我們以后介紹。
盡管部署描述符格式的文件ejb- jar.xml對所有ejb Server都是共有的。你可以從sun得到一個正確定義的DTD, 但是沒有為一個特殊EJB Server指明每個必須要求。也沒有說明如何從ejb-name影射到部署的JNDI名字,例如“[application name]/[bean name]”。通過JBoss提供一個缺省行為,來進行工作。這些工作來自于ejb-jar.xml。在高級配置的案例中,你必須定義JBoss說明行 為, 此行為用jboss.xml部署描述符。在高級配置中我們會談到jboss.xml描述符的詳細信息的。
這里我們僅配置 jboss.xml描述符的JNDI名字來用來訪問Interest EJB home inrterface。通過缺省的JNDI名字用來訪問EJB home inrterface, 需要同ejb-jar.xml的ejb-name相同。對于這個簡單的例子,Interest bean通過JNDI初始化上下文(作為“Interest”)來定位。 我們想用“interest/Interest”使home interface 可以使用,所以我們必須用jboss.xml描述符來說明。在jboss.xml中,重新覆蓋缺省的JNDI命名。為了重新編寫缺省的行為,我們用ejb -jar.xml中的ejb-name元素值作為bean home接口的JNDI命名,必須說明jndi命名,來寫jboss.xml描述符如下:
<?xml version="1.0" encoding="UTF-8"?>
<jboss>
<enterprise-beans>
<session>
<ejb-name>Interest</ejb-name>
<jndi-name>interest/Interest</jndi-name>
</session>
</enterprise-beans>
</jboss>
這個文件說明調用的Interest BEAN被綁定在interest/Interest的JNDI名稱下。我們建立的標準ejb-jar.xml部署描述符同JBoss說明 jboss.xml共同設置Interest EJB home接口的JNDI名稱為“interest/Interest”。我們現在有了EJB類,這些類是建立ejb 文件包必須的文件。
3、打包和部署BEAN
jar包是建立一個JAR文件,該文件包含EJB類文件和部署描述符。在下載的例子可能和你設置環
境不同,所以需要修改examplesuilduild.xml的內容。關于各個ant方面的內容,我會在Ant文檔中介紹給大家。關于如何修改,下面我一步步地來告訴大家。以下是windows平臺的。至于Unix/Lunix平臺基本相似,這里就不在敘述了。
1) 在修改之前,比首先設定JBOSS_DIST環境變量,指定到你安裝的Jboss的目錄。我安裝在C:jboss-3.0.6_tomcat-4.1.18, 所以 JBOSS_DIST設定為C:jboss-3.0.6_tomcat-4.1.18。
2) 你是否安裝了tomcat或jetty等web服務器。如果你沒有安裝,建議你安裝jboss-3.0.6_tomcat-4.1.18, JBoss和tomcat直接結合在一起啦,不需要再單獨安裝,當然也可以安裝jboss-jetty( JBoss和jetty直接結合在一起)。取決你喜歡什么web服務器。
3) 完成上面兩步后,我們來討論修改examplesuilduild.xml文件。在原有的文件中的部分代碼:
<target name="validate-servlet">
<!-- Override with your web server servlet jar location.
The default assumes that JBOSS_DIST points to a
JBoss/Tomcat bundle distribution
-->
<available property="servlet.jar" value="${env.JBOSS_DIST}/../tomcat/lib/servlet.jar" file="${env.JBOSS_DIST}/../tomcat/lib/servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../jetty/lib/javax.servlet.jar" file="${env.JBOSS_DIST}/../jetty/lib/javax.servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar" file="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar" file="${env.TOMCAT_HOME}/lib/servlet.jar"/>
<property name="servlet.jar" value="COULD_NOT_FIND_SERVLET_JAR"/>
<path id="base.path_22">
<pathelement location="${jboss.dist}/client/ejb.jar"/>
<pathelement location="${jboss.dist}/client/jaas.jar"/>
<pathelement location="${jboss.dist}/client/jbosssx-client.jar"/>
<pathelement location="${jboss.dist}/client/jboss-client.jar"/>
<pathelement location="${jboss.dist}/client/jnp-client.jar"/>
<pathelement location="${servlet.jar}"/>
</path>
<path id="base.path_24">
<pathelement location="${jboss.dist}/client/jboss-j2ee.jar"/>
<pathelement location="${jboss.dist}/client/jaas.jar"/>
<pathelement location="${jboss.dist}/client/jbosssx-client.jar"/>
<pathelement location="${jboss.dist}/client/jboss-client.jar"/>
<pathelement location="${jboss.dist}/client/jnp-client.jar"/>
<pathelement location="${servlet.jar}"/>
</path>
</target>
<target name="validate-jboss" depends="validate-servlet">
<available property="classpath_id" value="base.path_22" file="${jboss.dist}/client/ejb.jar" />
<available property="classpath_id" value="base.path_24" file="${jboss.dist}/client/jboss-j2ee.jar" />
</target>
由于此代碼例子是jboss2.2中的所以對于我們不能適應,在此基礎上我們來進行改動。在改動之前,來說明一下為什么改動,讓大家清楚改動原因,不是一團霧水。
<available property="servlet.jar" value="${env.JBOSS_DIST}/../tomcat/lib/servlet.jar" file="${env.JBOSS_DIST}/../tomcat/lib/servlet.jar"/>….
此部分說明你運用的web服務器是什么,根據你使用的web服務器來設置servlet.jar。 由于我使用的是jboss-tomcat.。
<path id="base.path_24"> … </path>說明客戶端要的CLASSPATH包。
修改以后的部分文件:
<target name="validate-servlet">
<!-- Override with your web server servlet jar location.
The default assumes that JBOSS_DIST points to a
JBoss/Tomcat bundle distribution
-->
<available property="servlet.jar" value="${env.JBOSS_DIST}/tomcat-4.1.x/common/lib/servlet.jar" file="${env.JBOSS_DIST}/tomcat-4.1.x/common/lib/servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../jetty/lib/javax.servlet.jar" file="${env.JBOSS_DIST}/../jetty/lib/javax.servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar" file="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar"/>
<available property="servlet.jar" value="${env.JBOSS_DIST}/../catalina/common/lib/servlet.jar" file="${env.TOMCAT_HOME}/lib/servlet.jar"/>
<property name="servlet.jar" value="COULD_NOT_FIND_SERVLET_JAR"/>
<path id="base.path_22">
<pathelement location="${jboss.dist}/client/ejb.jar"/>
<pathelement location="${jboss.dist}/client/jaas.jar"/>
<pathelement location="${jboss.dist}/client/jbosssx-client.jar"/>
<pathelement location="${jboss.dist}/client/jboss-client.jar"/>
<pathelement location="${jboss.dist}/client/jnp-client.jar"/>
<pathelement location="${servlet.jar}"/>
</path>
<path id="base.path_306">
<pathelement location="${jboss.dist}/client/jboss-j2ee.jar"/>
<pathelement location="${jboss.dist}/client/jboss-jaas.jar"/>
<pathelement location="${jboss.dist}/client/jbosssx-client.jar"/>
<pathelement location="${jboss.dist}/client/jboss-client.jar"/>
<pathelement location="${jboss.dist}/client/jnp-client.jar"/>
<pathelement location="${jboss.dist}/client/jbossall-client.jar"/>
<pathelement location="${jboss.dist}/client/log4j.jar"/>
<pathelement location="${servlet.jar}"/>
</path>
</target>
<target name="validate-jboss" depends="validate-servlet">
<available property="classpath_id" value="base.path_22" file="${jboss.dist}/client/ejb.jar" />
<available property="classpath_id" value="base.path_306" file="${jboss.dist}/client/jboss-j2ee.jar" />
</target>
4)修改完后存盤。然后到exaplesuild目錄下運行以下命令:
ant intro-interest-jar
如果成功會提示 : BUILD SUCCESSFUL 。
在編譯EJB 類文件,建立ejb-jar文件時,如果有一個java.lang.NoClassDefFoundError異常產生,你需要檢查你的classpath。修改<path id="base.path_306">中的內容。
5)完成后你可以查看interest.jar文件中內容:
jar ?tvf interest.jar為了把bean部署到server上,必須拷貝interest.jar文件到JBOSS_DIST/server/default/deploy目錄下。服務器自己會發現發生變化的文件,并重新部署它。
6)當JBoss server運行時,通過在examlpesuild目錄下運行ant intro-interest-deploy來部署jar。在你部署期間,你會看到在server控制臺的一些信息。
7)如果你發現部署失敗的信息,通常是部署描述符ejb-jar.xml文件結構壞了或丟失或在錯誤的目錄下。
8)如果在Server上部署完后,我們來編寫一個簡單客戶端來測試它是否正常工作。
4、 編碼和編譯客戶端
單獨一個ejb是不能用,我們至少需要一個簡單客戶端來用它的服務。一個EJB可以被其他的EJB,普通的JavaBean,一個JSP page,一個applet程序或是獨立的應用程序調用。在這個例子中。我們編寫一個簡單的應用程序。這個應用程序將會建立Interest類的一個對 象。并且執行它的方法。當部署完bean后,server會綁定EJB home 接口到interest/Interest的JNDI名字下,并輸出此home 接口,能通過RMI被調用。客戶端代碼如下:
package org.jboss.docs.interest;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.rmi.PortableRemoteObject;
import org.jboss.docs.interest.Interest;
import org.jboss.docs.interest.InterestHome;
/** This simple application tests the ´Interest´ Enterprise JavaBean which is
implemented in the package ´org.jboss.docs.interest´. For this to work, the
Bean must be deployed on an EJB server.
*/
public class InterestClient
{
/** This method does all the work. It creates an instance of the Interest EJB on
the EJB server, and calls its `calculateCompoundInterest()´ method, then prints
the result of the calculation.
*/
public static void main(String[] args)
{
// Enclosing the whole process in a single `try´ block is not an ideal way
// to do exception handling, but I don´t want to clutter the program up
// with catch blocks
try
{
// Get a naming context
InitialContext jndiContext = new InitialContext();
System.out.println("Got context");
// Get a reference to the Interest Bean
Object ref = jndiContext.lookup("interest/Interest");
System.out.println("Got reference");
// Get a reference from this to the Bean´s Home interface
InterestHome home = (InterestHome)
PortableRemoteObject.narrow(ref, InterestHome.class);
// Create an Interest object from the Home interface
Interest interest = home.create();
// call the calculateCompoundInterest() method to do the calculation
System.out.println("Interest on 1000 units, at 10% per period, compounded over 2 periods is:");
System.out.println(interest.calculateCompoundInterest(1000, 0.10, 2));
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
}
客戶端在JNDI命名“interest/Interest”下查找InterestHome接口。如果你提供了一個正確的jboss.xml文件, Bean home接口將會綁定到這個名字。否則,JNDI的名字是“Interest”。為了連接JBoss JNDI,必須建立一個初始化上下文,該上下文是根據在客戶端的classpath路徑下jndi.properties來的。這個 jndi.property文件我們放在了examples esourcesjndi.properties中。代碼如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
指定了InitialContextFactory(初始化上下文工廠),url,和工廠對象的包。在這里url是“localhost”,或運行 JBoss的主機名(IP),用的缺省端口是1099。為了不同RMI協議互相兼容,通過“narrow”方法來確保“ref”對象能轉換為 “InterestHome”對象。客戶端不需要必須和EJB類在同一個包中。所以它必須import ejb claess類。
為了能運行Ant命令。我修改了examplesorgjbossdocsinterestuild.xml文件,原文件的部分內容:
<target name="deploy-ejb-jar" depends="ejb-jar">
<copy file="${build.interest.dir}/interest.jar" todir="${jboss.dist}/deploy" />
</target>
<target name="deploy-ear" depends="ear">
<copy file="${build.interest.dir}/interest.ear" todir="${jboss.dist}/deploy" />
</target>
修改后為:
<target name="deploy-ejb-jar" depends="ejb-jar">
<copy file="${build.interest.dir}/interest.jar" todir="${jboss.dist}/server/default/deploy" />
</target>
<target name="deploy-ear" depends="ear">
<copy file="${build.interest.dir}/interest.ear" todir="${jboss.dist}/server/default/deploy" />
</target>
修改完后保存。編譯和運行InterestClient,通過以下命令:
ant intro-interest-client會出現正確的結果。
5、補充說明
各個jar文件:
1) jboss-j2ee.jar :是標準的javax.ejb.* 包括EJB2.0接口和類。
2) jboss-jaas.jar :是java鑒定和授權服務安全類。
3) jbosssx-client.jar :是JbossSX安全擴展客戶端類。
4) jboss-client.jar :是Jboss EJB容器代理和stub客戶端類。
5) jnp-client.jar :是JBoss JNDI提供者客戶端類。
現在隱藏代碼,編譯和部署EJB, 運行簡單客戶端進行測試。
6、 結論
最后來進行一個總結。
Server:
為每個EJB(包括有、無狀態的Session,或實體Bean),都需要三個文件: bean實現類, remote接口類,home接口類。這些類和一個或多個部署描述符(ejb-jar.xml, jboss.xml等),這些描述符必須在META-INF目錄下,一起打包進jar文件。為部署這個jar文件,你只需要拷貝到 jbossserverdefaultdeploy下。
Client:
1)從JNDI服務,查找bean的home 接口;
2)從home接口,建立一個新的bean或得到一個已經存在bean;
3)用得到的remote接口來訪問服務器上bean實現類中商業方法。
在客戶端查找home 接口之前,客戶端必須知道如何從JNDI來定位。因此我們提供了一個jndi.properties文件。這個文件和一些jbossclientx下的jar,必須包含到CLASSPATH中,才能使客戶端運行。
摘自:天極網 時間:2003年9月11日