| 8.3和Jetty集成 Jetty web container已經(jīng)存在了很長時間并使可靠的。它是小的,快的并且有一個活躍的開發(fā)者社區(qū)。Jetty提供了許多和Tomcat相同的特性因為它們都是基于Java Servlet spec,但是每個實現(xiàn)都是特殊的。 Jetty本質(zhì)上是一個構(gòu)建一個web容器的工具包,它可以在許多方面定制。Out of box,Jetty是bare-bones的,但是它有一些配置文件這樣徐東不同的組合服務(wù)能在Jetty中啟動。這種程度的定制是有意的和允許極端的靈活性。Jetty Hightide是分布式的Jetty,有一組默認啟用的服務(wù)。Jetty Hightide最好的描述是它的文檔: Hightide 是一個optimized,versioned的分布式Jetty 開源web容器。它預(yù)先集成了一定數(shù)量的僅在J2EE應(yīng)用服務(wù)器中找到的服務(wù),或者是你不得不craft together yourself:JNDI,一個XA transaction service,一個JMS消息fabric,和一個JDBC可訪問數(shù)據(jù)庫。感謝Jetty的lightweight,pluggable architecture,Hightide 允許你簡單地選擇你想要使用的服務(wù),或者甚至使用其他的替換它們。 在本章節(jié)中,ActiveMQ將使用一個local JNDI配置和一個global JNDI配置集成到Jetty Hightide。為該章節(jié)從Codehaus下載Jetty Hightide 7.0.2.v20100331(http:///Sk6u)并解壓到你的電腦上。 Jetty為JNDI資源配置提供了三種風格:local,影響在Jetty上布置的所有應(yīng)用的global和影響在JVM上布置的所有應(yīng)用的global。在這些JNDI配置風格中有些不同,有些能通過Jetty的特性控制,該特性提供了scopt JNDI資源到一個特定的context的能力。Jetty的JNDI的scopting是強大的并能在該章節(jié)中被利用,但是僅是minimally。為了更深地了解Jetty的scopeJNDI資源的能力,看一下Jetty的global JNDI信息(http:///x67C)。我們將演示的這兩種風格的JNDI配置是local JNDI和global JNDI.這兩種風格的配置類似于在Tomcat中它們的配置,但是配置格式是獨特的。 注意 local JNDI配置示例和global JNDI配置示例無法同時部署。因為這會導(dǎo)致classloader issues并使ActiveMQ無法正確部署。確保某刻只部署某一個風格的配置。 8.3.1使用local JNDI來在Jetty中集成ActiveMQ Jetty的local JNDI配置也在資源定義的地方限制了資源對于應(yīng)用的可用性。JNDI資源在一個文件中定義,該文件存在于web應(yīng)用中名為WEB-INF/jetty-env.xml,顯示如下。 Listing 8.8 The Jetty jetty-env.xml file <Configure id='jms-webapp-wac' class="org.foo.mortbay.jetty.webapp.WebAppContext"> <New id="connectionFactory" class="org.mortbay.jetty.plus.naming.Resource"> <Arg> <Ref id='jms-webapp-wac' /> </Arg> <Arg>jms/ConnectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?brokerConfig=xbean:activemq.xml</Arg> </New> </Arg> </New> <New id="fooQueue" class="org.mortbay.jetty.plus.naming.Resource"> <Arg>jms/FooQueue</Arg> <Arg> <New class="org.apache.activemq.command.ActiveMQQueue"> <Arg>FOO.QUEUE</Arg> </New> </Arg> </New> </Configure> 在表8.8的配置特定于Jetty,并且它通過一個對示例web應(yīng)用的基本的JNDI查找告訴Jetty來使三個資源有效。注意表8.8包含了ActiveMQ連接工廠定義和一個ActiveMQ queue定義。關(guān)于jms-webapp-wac context identifier限制了這些資源對于該web app context(local context)的可用性。 注意 $JETTY_HOME變量一般被用來指向Jetty Hightide的安裝目錄,它并不是必須在你的環(huán)境中設(shè)置的。 測試在jetty中的local JNDI配置可使用下面的步驟: 第一步 復(fù)制jms-webapp-local/target/jms-webapp.war文件到$JETTY_HOME/webapps目錄。 第二步 使用下面的命令啟動Jetty Hightide: $ cd $JETTY_HOME $ java -jar ./start.jar 2010-04-08 21:06:51.994:INFO::Logging to StdErrLog::DEBUG=false via org.eclipse.jetty.util.log.StdErrLog ... INFO - BrokerService - ActiveMQ 5.4.1 JMS Message Broker (FooBroker) is starting ... 2010-04-08 21:07:01.995:INFO::Started SelectChannelConnector@0.0.0.0:8080 該輸出說明ActiveMQ使用activemq.xml配置文件因為在那個文件中brokerName FooBroker被指定了。再一次,如在本章開頭所說的,該配置利用了ActiveMQ的獨特特性。該特性允許ActiveMQ代理通過建立一個連接工廠并傳遞給它一個代理URI來啟動。這個連接工廠嘗試連接該URI上的代理并如果沒有,它將啟動一個這樣的代理。 第三步 訪問http://localhost:8080/jms-webapp并使用顯示在圖8.4上的圖來發(fā)送一個消息。 第四步 通過檢查控制臺顯示的輸出來確認消息已經(jīng)被成功發(fā)送了: ...
2010-04-08 21:07:01.995:INFO::Started SelectChannelConnector@0.0.0.0:8080
INFO - SingleConnectionFactory - Established shared JMS Connection:
ActiveMQConnection {id=ID:mongoose.local-61512-1270782421187-2:1,
clientId=null,started=false}
INFO - JmsMessageDelegate - Consumed message with payload:
This is a test message
注意從Jetty上的輸出。從JmsMessageDelegateListener bean的日志消息顯示了消息被consumed并消息正文被logged。 這展示了為ActiveMQ資源配置local JNDI context是被Jetty支持的。在Jetty application server中說明都不需要改變。因為配置已在示例web應(yīng)用中。local JNDI context相對的就是global JNDI context。 8.3.2使用global JNDI在Jetty中集成ActiveMQ Jetty的global JNDI配置文件需要不同的配置,但是XML配置幾乎和local JNDI XML配置完全相同。不同點事它必須將它放在不同的地方。為了該演示,global JNDI配置已經(jīng)在etc/jetty.xml文件內(nèi)配置,如下顯示: Listing 8.9 The Jetty jetty.xml file ... <New id="connectionFactory" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg> <Ref id="Server"/> </Arg> <Arg>jms/ConnectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?brokerConfig=xbean:etc/activemq.xml</Arg> </New> </Arg> </New> <New id="fooQueue" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg>jms/FooQueue</Arg> <Arg> <New class="org.apache.activemq.command.ActiveMQQueue"> <Arg>FOO.QUEUE</Arg> </New> </Arg> </New> <New id="fooTopic" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg>jms/FooTopic</Arg> <Arg> <New class="org.apache.activemq.command.ActiveMQTopic"> <Arg>FOO.TOPIC</Arg> </New> </Arg> </New> ... 注意在表8.9和Jetty中l(wèi)ocal JNDI XML配置相比僅稍有不同。不同的是第一個<Arg>元素涉及Server--整個Jetty server。這個Jetty的scoping特性示例,它告訴Jetty expose該資源到Server對象--整個server(它將在同一個文件中被定義)。 驗證在Jetty中的global JNDI資源的定義,使用下面的步驟: 第一步 建立如下新目錄:$JETTY_HOME/lib/ext/activemq。 第二步 復(fù)制如下列表的JARs到在第一步中創(chuàng)建的文件夾中: ■ activemq-all-5.4.1.jar ■ spring-context-2.5.6.jar ■ aopalliance-1.0.jar ■ spring-context-support-2.5.6.jar ■ commons-logging-1.1.1.jar ■ spring-core-2.5.6.jar ■ geronimo-j2ee-management_1.0_spec-1.0.jar ■ spring-jms-2.5.6.jar ■ geronimo-jms_1.1_spec-1.1.1.jar ■ spring-tx-2.5.6.jar ■ log4j-1.2.14.jar ■ spring-web-2.5.6.jar ■ org.osgi.core-4.1.0.jar ■ spring-webmvc-2.5.6.jar ■ spring-aop-2.5.6.jar ■ xbean-spring-3.4.3.jar ■ spring-beans-2.5.6.jar 再一次,獲取這些JARs的最快捷的地方是在在編譯以后的jms-webapp-local項目里。在使用Maven編譯這個項目之后,你將能夠在jms-webapp-local/target/jms-webapp/WEB-INF/lib/目錄下找到JARs。僅需復(fù)制它們到$JETTY_HOME/lib/ext/activemq目錄。 第三步 編譯jms-webapp-global目錄并建立WAR文件,在命令行運行如下的命令: $ mvn clean install ... [INFO] Scanning for projects... [INFO] ---------------------------- ----- [INFO] Building jms-webapp-global [INFO] task-segment: [clean, install] [INFO] ---------------------------- ----- ... [INFO] ---------------------------- ----- [INFO] BUILD SUCCESSFUL [INFO] ---------------------------- ----- ... 運行這個命令之后,一個WAR文件將出現(xiàn)在target文件夾下。 第四步 復(fù)制jms-webapp-global/activemq.xml文件到$JETTY_HOME/etc/activemq.xml中。這使ActiveMQ配置文件在classpath上可用。 第五步 復(fù)制jms-webapp-global/target/jms-webapp.war到$TOMCAT_HOME/webapps目錄。這將部署示例web應(yīng)用。 第六步 使用如下命令啟動Jetty: $ java -jar start.jar 2010-04-11 21:41:23.253:INFO::Logging to StdErrLog::DEBUG=false via org.eclipse.jetty.util.log.StdErrLog ... INFO - BrokerService - ActiveMQ 5.4.1 JMS Message Broker (FooBroker) is starting ... 2010-04-11 21:41:33.116:INFO::Started SelectChannelConnector@0.0.0.0:8080 你能從上面代理啟動的輸出中看到ActiveMQ在使用activemq.xml配置文件因為brokerName FooBroker在那個文件中被指定了。 第七步 訪問http://localhost:8080/jms-webapp并使用在圖8.4中顯示的頁面來發(fā)送一個消息。 第八步 通過檢查控制臺查看下面的輸出verify消息已成功發(fā)送和消費: ... 2010-04-11 21:41:33.116:INFO::Started SelectChannelConnector@0.0.0.0:8080 INFO - SingleConnectionFactory - Established shared JMS Connection: ActiveMQConnection {id=ID:mongoose.local-61512-1270782421187-2:1, clientId=null,started=false} INFO - JmsMessageDelegate - Consumed message with payload: This is a test message 再一次,注意Jetty運行的輸出。從JmsMessageDelegateListener bean的輸出展示了消息已經(jīng)被consumed。 Jetty的global JNDI配置提供了與Tomcat相同的優(yōu)點。如果在單個Jetty實例上部署的多一個應(yīng)用需要對JNDI資源的訪問權(quán),這是個很好的選擇。 Tomcat和Jetty是兩個能很好和集成ActiveMQ的web 容器示例。web容器之外是非常完善的Java EE應(yīng)用服務(wù)器如Apache Geronimo和JBoss。 | 
|  |