EJB3: JBOSS 企業版、JBOSS服務器構架、EJB2.0 HelloWrold實例

本文的研究基於jboss-eap-4.3,一開始解決一個問題,接下來實驗jboss-eap-4.3的一些簡單屬性。

1. 解決一個簡單問題

問題如上一篇博客描述:jboss-eap-4.3啓動時停滯在Configuring from URL: resource:jboss-log4j.xml ,詳細描述可以參見鏈接http://kylinsoong.iteye.com/blog/793215

問題解決:

先區別兩個不同版本的JBOSS:jboss-4.2.2.GAjboss-eap-4.3:

 

jboss-4.2.2.GA jboss-eap-4.3
      普通JBOSS,完全開源,相比較簡單,用於簡單個人的實驗與測試,啓動時顯示啓動完全過程,即啓動時間。       eap(Enterprise Application)指JBOSS企業版,與jboss-4.2.2.GA相比企業版的JBOSS加入安全性,穩定性等方面的考慮,沒有完全開源,用於企業部署與應用。

 

 

 

 

 

 

所以綜上兩個版本在功能上沒有區別。

      對於經常使用普通版JBOSS的人第一次使用企業版JBOSS,啓動企業版JBOSS,啓動完成後不顯示啓動時間及啓動詳細過程,當啓動停滯在Configuring from URL: resource:jboss-log4j.xml 時啓動已經完成,完成界面如下:

 當出現上述界面說明JBOSS企業版已經啓動完成,這時可以點擊http://localhost:8080/查看,爲什麼Jboss企業版不在Console口輸出大量日誌呢?個人認爲出於兩方面原因:一是是出去JBoss性能考慮,日誌輸出實際是大量的IO操作,消耗大量資源;另一方面,日誌信息是供開發人員測試使用,Jboss企業版,注重的是企業應用,所以,不需要向Console臺輸出大量日誌,當然爲了我們調試方便,我們可以修改相關日誌配置文件,輸出相關日誌信息,供我們開發,調試,相關日誌控制文件位置jboss-eap-4.3\jboss-as\server\<configure version>\conf\jboss-log4j.xml;

      至此http://kylinsoong.iteye.com/blog/793215提出的問題得以解決,由此可見這個問題絕對是一個新手錯誤,犯錯的主要原因是犯錯者習慣使用普通版JBOSS。

2. JBoss eap Quick starting

      關於JBoss企業版下載,參見http://kylinsoong.iteye.com/blog/784231;

JBoss目錄結構:

解壓jboss-eap-4.3後目錄結構如下圖:



 

jboss-as                   最高層目錄,包含Jboss啓動的腳步文件、jar文件、配置文件、工作目錄等,系統設置JBOSS_HOME就是到這層目錄,即(%\jboss-eap-4.3\jboss-as)
seam 包含JBoss seam Framework和Hibernate相關文件
jboss-as\bin 包含系統啓動,關閉及一些系統特定腳步
jboss-as\client 存儲Java Client Application或外部Web 容器可能使用到的配置文件和jar文件,jbossall-client.jar(上篇博客中JNDI客戶端代碼用到的jar)就存儲於此
jboss-as\docs 存儲了一些例子配置文件,比如要使用Entity Bean管理Oracle,可以在此位置找到Oracle JCA相關配置文件樣本
jboss-as\server

包含Jboss服務的配置種類,jboss提供四種配置設置:minimal,default, production, 和 all,

動時不指定,默認啓動的是production設置,這四種設置分別對應jboss-as\server下四個子文件夾:

minimal:啓動logging service、JNDI server、URL deployment Scanner

default:包含J2EE1.4所必須的一些service和部署J2EE所常用的一些Service,不包括JAXR   service、IIOP Service和任何集羣的Service

all:基本包括所有常見service,如JAXR   service、IIOP Service和任何集羣的Service等

production:基於all配置,加入了日誌冗長處理(減少),每隔60秒掃描一次部署組建功能,和內存按需分配等,也是默認的啓動選項

jboss-as\server\production\conf 包含Jboss啓動的引導文件jboss-service.xml,該文件包含jboss要啓動的核心服務的描述
jboss-as\server\production\deploy 包括熱部署服務,你部署的服務(jar、war、ear)
jboss-as\server\production\conf\props 包含一些安全設置的配置文件,例如解壓完修改此文件下jmx-console-users.properties文件,你纔可以訪問jmx-console,否則你沒有權限
jboss啓動實例 run.bat -c production -b 0.0.0.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

啓動完成後可以通過http://localhost:8080/jmx-console/來訪問JMX Console,如果沒有權限訪問,修改jboss-as\server\production\conf\props下jmx-console-users.properties配置文件;

3. Jboss服務器構架

分析一個關於Jboss服務器構架的圖片



Jboss模塊的構架是建立在底層JMX之上;

JMX作爲底層總線,基於可插入式的服務器設計理念(EJB容器,Web服務等);

容器的設計採用反射機制;

JBOSS主要模塊:

 

EJB Container  JBoss服務器的核心實現,它有兩個特性,第一是在運行期產生EJB 對象的Stub和Skeleton類,第二是支持熱部署
Web Server 支持Web容器和Servlet引擎
JBossTx JBossTX架構被設計成爲可以使用任何的實現了JTA接口的交易管理
JBossCx JBossCX實現了部分JCA的功能。JCA制訂了J2EE應用組件如何訪問基於連接的資源(數據庫)
Deployment 支持EJB(jar)、Web應用文檔(war)和企業級應用文檔(ears)的部署。它會時刻關心J2EE應用的URL情況,一旦它們被改變或出現的時候將自動部署。
JBossSx 安全相關的實現
JBossNS JBossNS是JBoss命名服務用來定位對象和資源。它實現了JNDI J2EE規範
JBossMQ JBossMQ使Java 消息規範(JMS)的實現

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

關於JMX

JMX(Java Management Extensions)是一個爲應用程序植入管理功能的框架,JMX致力於解決分佈式系統管理的問題。JMX可以看做分爲三層:表現層(實現層)、代理層、分佈式服務層,如下圖所示,最下面屬於表現層,中間代理層,最上面屬於分佈式服務層:

表現層:JMX可管理資源所在的層,這些已管理的資源可以編寫或封裝爲MBean,MBean分爲四種類型: 標準、動態、開放、模型;

代理層:代理層相當於一個MBean服務器,用來管理MBean如何和分佈式層的服務連接,連接這些分佈式服務一般用的是相關的Adapter或連接器;

分佈式服務層:如RMI管理應用、基於瀏覽器的管理控制等
詳細可以參考:http://www.blogjava.net/mlh123caoer/archive/2007/09/03/142456.html

4. EJB 容器 on JBoss

重申兩個名詞:

EJB:可部署的組件,能夠被裝配成完整的解決方案

EJB容器:提供一組標準服務:分佈式對象、事務、持久性、安全性和併發性 

客戶端與JBOSS EJB組件系統的交互

 

 由圖可見EJB客戶端與EJB組件的交互主要是與EJB各類bean之間的交互;

 企業Bean的組成部分:

 

Enterprise Bean類

業務邏輯核心,不包含與網絡有關的邏輯功能;

依照明確定義的接口並且遵守某些規則,能運行於任何EJB容器中;

實現javax.ejb.SessionBean/EntityBean/MessageDrivenBean接口

客戶端不直接對實際的Enterprise Bean類的實例進行調用

遠程接口

複製Bean類公開的所有商務邏輯方法,具有網絡功能;
擴展javax.ejb.EJBObject接口,遵守RMI-IIOP參數傳遞約定,遠程對象(EJB Object)的方法必須拋出java.rmi.RemoteException異常;

EJB Object是EJB容器的一部分;

客戶端調用EJB Object中的方法

Home接口:EJB工廠

EJB Object的生成庫:生成EJB Object,查找現存的EJB Object,刪除EJB Object,負載均衡等;
擴展javax.ejb.EJBHome接口,遵守RMI-IIOP參數傳遞約定,方法必須拋出java.rmi.RemoteException異常;

EJB Home Object是EJB容器的一部分;

客戶端從Home接口獲得對EJB Object的引用

本地接口

如果調用的Enterprise Bean在同一進程中,不必經過Stub、Skeleton、網絡調用以及參數的編組和解組;

擴展javax.ejb.EJBLocalObject接口;

通過引用而不是值來對參數進行編組;

本地Home接口

通過本地調用創建或查找EJB,與本地接口對應

部署描述文件:ejb-jar.xml 描述文件名:ejb-jar.xml
確定要運行的是哪一種EJB、Home接口、遠程接口和Bean類的名字等信息;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 向JBoss EJB容器中部署一個EJB2.0的HelloWorld應用:

Step 1:定義企業bean HelloWorldBean

public class HelloWorldBean implements SessionBean {
	
	private SessionContext mySessionCtx;
	
	public SessionContext getMySessionCtx() {
		return mySessionCtx;
	}

	public void setMySessionCtx(SessionContext mySessionCtx) {
		this.mySessionCtx = mySessionCtx;
	}

	public void ejbCreate() throws EJBException, RemoteException{
		System.out.println("EJB Created");
	}
	
	public void ejbActivate() throws EJBException, RemoteException {}

	public void ejbPassivate() throws EJBException, RemoteException {}
	
	public void ejbRemove() throws EJBException, RemoteException {}

	public void setSessionContext(SessionContext arg0) throws EJBException,
			RemoteException {}

	public String helloWorld() throws EJBException, RemoteException{
		return "Hello World.  Welcome to EJB!";
	}

}

 

Step 2:定義遠程接口HelloWorld

public interface HelloWorld extends EJBObject {
	public String helloWorld() throws RemoteException;
}

 Step 3:定義Home接口HelloWorldHome

public interface HelloWorldHome extends EJBHome {
	public HelloWorld create() throws CreateException, RemoteException;
}

 

Step 4: 定義部署描述文件ejb-jar.xml

<?xml version="1.0"?>  
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
	<enterprise-beans>
		<session>
			<ejb-name>HelloWorld</ejb-name>
			<home>com.home.ejb.home.HelloWorldHome</home>
			<remote>com.home.ejb.remote.HelloWorld</remote>
			<ejb-class>com.home.ejb.bean.HelloWorldBean</ejb-class>
			<session-type>Stateless</session-type>
			<transaction-type>Bean</transaction-type>
		</session>
	</enterprise-beans>
</ejb-jar>

 Step 5:定義JNDI描述文件jboss.xml

<?xml version="1.0" encoding="gb2312"?>  
<jboss>  
    <enterprise-beans>  
        <session>  
            <ejb-name>HelloWorld</ejb-name>  
            <jndi-name>ejb/HelloWorld</jndi-name>  
        </session>  
    </enterprise-beans>  
</jboss>

 Step 6:定義打包部署文件build.xml

<?xml version="1.0"?>  
<project name="com.home.ejb" default="deploy" basedir="..">  
  
    <property environment="env" />  
    <property name="app.dir" value="${basedir}\com.home.ejb" />  
    <property name="src.dir" value="${app.dir}\src" />  
    <property name="jboss.home" value="${env.JBOSS_HOME}" />  
    <property name="jboss.server.config" value="production" />  
    <property name="build.dir" value="${app.dir}\build" />  
    <property name="build.classes.dir" value="${build.dir}\classes" />  
  
    <path id="build.classpath">  
            <fileset dir="${jboss.home}\client">  
                <include name="*.jar" />             
            </fileset>  
            <pathelement location="${build.classes.dir}" />  
    </path>  
       
    <target name="prepare" depends="clean">  
            <mkdir dir="${build.dir}" />  
            <mkdir dir="${build.classes.dir}" />  
    </target>  
       
    <target name="clean">  
            <delete dir="${build.dir}" />  
            <delete file="${jboss.home}\server\${jboss.server.config}\deploy\helloworld.jar" />  
    </target>  
       
    <target name="compile" depends="prepare" >  
            <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" optimize="off" includes="com/**">  
                <classpath refid="build.classpath" />  
            </javac>  
    </target>  
       
    <target name="ejbjar" depends="compile" >  
        <jar jarfile="${app.dir}\helloworld.jar">   
            <fileset dir="${build.classes.dir}">  
                <include name="com/**/*.class" />  
            </fileset>  
        	<metainf dir="${app.dir}/META-INF">
				<include name="ejb-jar.xml" />
				<include name="jboss.xml" />
        	 </metainf>
        </jar>  
    </target>  
       
    <target name="deploy" depends="ejbjar">  
        <copy file="${app.dir}\helloworld.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy" />  
    </target>  
  
</project>  

 

Step 7:ant運行build.xml,將組件部署到Jboss,部署成功Jboss console口會出現如下信息:

 http://localhost:8080/jmx-console/HtmlAdaptor下Global JNDI Namespace會出現如下JNDI綁定信息:

 Step 8:編寫客戶端調運代碼:

public class HelloWorldClient {
	public static void main(String[] args) {
        Properties properties = new Properties();   
        properties.setProperty(Context.INITIAL_CONTEXT_FACTORY , "org.jnp.interfaces.NamingContextFactory");
        properties.setProperty(Context.PROVIDER_URL, "jnp://localhost");
        try {
			Context ctx = new InitialContext(properties);
			Object objRef = ctx.lookup("ejb/HelloWorld");  
			
			HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow(objRef, HelloWorldHome.class);
			
			HelloWorld helloworld = home.create();
			System.out.println(helloworld.helloWorld());
        } catch (NamingException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (CreateException e) {
			e.printStackTrace();
		} 
	}
} 

Step 9:運行客戶端代碼:

如上客戶端代碼功能可分爲三步如下:

1. 執行JNDI檢索,找出Home對象
2. 使用Home接口,創建一個EJB實例
3. 利用EJB實例,調用業務方法

Hello World.  Welcome to EJB!

Step 10:Eclipse下文件詳細描述:

 Step 11: 運行流程分析:

整個客戶端調運企業bean總helloworld方法可以分爲以用如下圖描述:



1.檢索Home對象引用
2.返回Home對象引用/Stub
3.創建新的EJB對象
4.生成EJB對象
5.返回EJB對象引用/Stub
6.調用業務方法
7.將請求委託給Bean

發佈了4 篇原創文章 · 獲贊 0 · 訪問量 1588
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章