既然已經有了WAR文件(或 CAB文件), 是時候轉向Web應用程序開發的部署了。若是你工做的機器自己就是一臺Web服務器,部署將簡單到只是把.war文件拷貝到服務器的相應應用程序目錄。例 8-2說明了這一點; 這個建立文件創建和拷貝了一個 .war文件到Tomcat的webapps 目錄.當你(重)啓動Tomcat,這個.war文件就會被自動釋放到一個同名的文件夾下(省去了.war擴展名),同時這個Web應用程序也就準備好了,在這個例子中,其URL是[url]http://localhost:8080/app[/url] (若是你正在部署一個Servlet, URL將會反映出Servlet的包結構,例如[url]http://localhost:8080/org/antbook/ch08/app[/url]說明Serlet類的結構org.antbook.ch08.app.)。
例 8-2. Tomcat部署的建立文件 (ch08/simple/build.xml)
<?xml version="1.0" encoding = "UTF-8"?> <project default="main" basedir="."> <property name="src" location="source" /> <property name="wardir" location= "c:/tomcat/jakarta-tomcat-5.0.19/webapps"/> <property name="warfile" location="${wardir}/app.war"/> <target name="main" depends="war"> <echo message="Deploying the Web app...."/> </target> <target name="war" > <war destfile="${warfile}" webxml="${src}/app.xml" basedir="${bin}" /> </target> </project>
你可使用Ant的 ftp 任務(查看第4章)來遠程地部署到一個Web服務器的基礎目錄下。
使用SCP來部署
另外一種從Ant 1.6開始的有效部署方式是SCP,它把一個文件或者FileSet從一個運行SSH (譯者注:指SSH daemon。Daemon- [計] Internet中用於郵件收發的後臺程序) 的遠程主機上拷貝 (或者拷貝到遠程主機上)。這種方式是一種可選的方式,並且你須要把jsch.jar 放到Ant的lib目錄下來使用 (你能夠從如下地址獲得jsch.jar: [url]http://www.jcraft.com/jsch/index.html[/url])。
用這種方式部署起來很方便。例如,下面是一個怎樣把一個單獨的文件部署到一臺遠程主機的例子 (任何的主機,除非你明確地設置trust的屬性爲yes或者true,不然它必定要在你的已知主機 (knownhosts) 列表中):
<scp file="Project.jar" todir="user:password@antmegacorp.com:/home/steven/cgi-bin"/>
你能夠明確的使用password屬性來設置密碼:
<scp file="Project.jar" todir="[email]user@antmegacorp.com[/email]:/home/steven/cgi-bin"" password="password"/>
如何拷貝一個遠程文件到本地機器:
<scp file="user:password@antmegacorp.com:/home/steven/cgi-bin/Project.jar" todir="${archive}"/>
如何利用fileset來拷貝一組文件:
<scp todir="user:password@antmegacorp.com: /home/steven/source"> <fileset dir="${src}"> <include name="**/*.java"/> </fileset></scp>
例8-3給出了一個完整的利用scp方式來部署的構造文件。(它使用了遠程主機的IP地址來代替了命名遠程服務器。)
例 8-3. 利用scp (ch08/scp/build.xml)
<?xml version="1.0" ?><project default="main"> <property name="message" value="Deploying the .jar file." /> <property name="src" location="source" /> <property name="output" location="bin" /> <target name="main" depends="init, compile, compress, deploy"> <echo> ${message} </echo> </target> <target name="init"> <mkdir dir="${output}" /> </target> <target name="compile"> <javac srcdir="${src}" destdir="${output}" /> </target> <target name="compress"> <jar destfile="${output}/Project.jar" basedir="${output}"> <include name="*.class"/> <include name="*.txt"/> </jar> </target> <target name="deploy"> <scp trust="true" file="${output}/Project.jar" todir="user:password@000.000.000.000:cgi-bin"/> </target> </project>
這是剛纔的構造文件在Windows機器上運行時候的樣子:
%ant
Buildfile: build.xml
init:
[mkdir] Created dir: C:\ant\ch08\scp\bin
compile:
[javac] Compiling 1 source file to C:\ant\ch08\scp\bin
compress:
[jar] Building jar: C:\ant\ch08\scp\bin\Project.jar
deploy:
[scp] Connecting to 000.000.000.000
[scp] Sending: Project.jar : 664
[scp] File transfer time: 1.32 Average Rate: 9502.27 B/s
[scp] done.
main:
[echo]
[echo] Deploying the .jar file.
[echo]
BUILD SUCCESSFUL
Total time: 12 seconds
小技巧: 正如在第4章的時候說過的同樣,在一個構造文件中對密碼和/或用戶名的顯式編碼 (hardcoding-也有人稱硬編碼) 是一種很差的選擇。使用屬性會是一種較好的辦法,象下面這樣:
<scp todir="${username}:${password}@antmegacorp.com: /home/steven/source" ...>
象下面這樣把用戶名和密碼傳遞給Ant:
ant -Dusername=steven -Dpassword=opensesame
在文件被scp 方式所拷貝的時候,它的Unix文件許可並無被保留(實際上它們獲得的是UMASK許可)。若是你想保留Unix許可,用Unix下的scp 命令來代替(例如, <execexecutable="scp" ... >).
表 8-3. scp任務屬性
你可使用fileset 元素來選擇一組文件來拷貝;若是你使用了fileset,你就必須爲todir屬性指定一個值. (fileset 元素只在你拷貝本地文件到遠程主機時可用)
部署到Tomcat
做爲servlet和JSP的參考Web服務器,Tomcat (可從[url]http://jakarta.apache.org/tomcat/[/url]獲得),自從它包含了自定義的Ant部署方式,就變得更吸引Ant開發者。
從你的Tomcat5複製文件server/lib/catalina-ant.jar到Ant的lib目錄來使用那些任務。
Tomcat部署任務包括部署, 從新加載,反部署 (卸載); 要使用他們,增長這些taskdef元素(在第11章討論了) 到你的建造文件:
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/> <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"/><taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/>
想使用這些任務, 你須要Tomcat管理員權限; 象下面這樣編輯conf/tomcat-users.xml爲一個用戶名增長管理員權限(這裏是admin)和口令:
<?xml version='1.0' encoding='utf-8'?><tomcat-users> <role rolename="manager"/> <role rolename="role1"/> <role rolename="tomcat"/> <user username="admin" password="password" roles="manager"/> <user username="role1" password="tomcat" roles="role1"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> </tomcat-users>
你能像下面這樣使用部署任務在Ant中部署一個Web應用程序到Tomcat:
<target name="install"> <deploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}" localWar="file://${build}"/> </target>
在這裏manager.url是Tomcat管理器的servlet的URL。
這servlet的缺省值名字是
「
manager
」
,所以看起來象[url]http://localhost:8080/manager[/url]。
app.path屬性表示的是這個應用程序應該被部署的上下文路徑(一般是
「
/
」
加上你想要在URL中聯機訪問的應用程序的的名字)。
build屬性表示的是在你要在什麼位置來創建Web應用程序,比喻說是Tomcat的webapps目錄。
若是你已經安裝一個應用程序而且想要Tomcat認出你最新的Java類,使用reload(從新加載任務)代替:
<target name="reload"> <reload url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}"/> </target>
刪掉一個Web應用程序, 使用undeploy任務:
<target name="remove"> <undeploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}"/> </target>
部署到Tomcat
更日常的狀況是,你將不會在你想部署到的服務器上進行你的應用程序的開發。 你能夠經過瀏覽器中的URL訪問到Tomcat管理器的Servlet進而達到在一臺運行了Tomcat的遠程主機上部署的目的。
在Ant中實現這一點你須要get任務,當你把一個URL傳遞給它時它獲得一份文件。若是你正在使用Java 1.4或更新版本,這個任務支持任何URL schema, 包括http:, ftp:, jar:,和 https:。若是你想要下載聯機的內容,那麼這個任務是較大的,或,如在本例中,經過URLs向聯機的代碼發佈命令。
在開始部署前,這個例子使用get命令修改Ant主頁並保存成ant.html:
<get src="http://ant.apache.org/" dest="ant.html"/>
你能經過傳遞一個要上傳的Web應用程序的本地位置給管理器的servlet來實現爲Tomcat上傳Web應用程序的目的。
例如,從Windows的C:/ant/ch08/app上傳一個Web應用程序,你將使用這個位置:
file:////C:\ant\ch08\app/
上傳一個.war文件, 你在位置的最後加一個!來講明你上傳的是一個文件而不是目錄的內容,在Unix中象下面這樣:
jar:file://///ant/ch08/app.war!/
例子8-3展現的是在實踐的如何工做。
在這個例子中, 構造文件從C: \ant\deploy\app(org.antbook.ch08.Deploy)部署一個Web應用程序到Tomcat,它包含一個顯示"Project Deployment"的servlet。
這是你要傳遞給的get任務的URL來告訴Tomcat管理器servlet你想要幹什麼:
[url]http://localhost:8080/manager/deploy?path=/deployment&[/url]
war=file:////c:\ant\deploy\app/
在例子8-4你能看到如何工做。
例子8-4 部署與get(ch08/get/build.xml)
<?xml version="1.0" encoding="UTF-8" ?> <project default="main" basedir="."> <property name="tomcat.port" value="8080" /> <property name="tomcat.username" value="admin" /> <property name="tomcat.password" value="password" /> <target name="main" > <get src="http://localhost:8080/manager/deploy?path=/deployment& war=file:////c:\ant\deploy\app/" dest="deploy.txt" username="${tomcat.username}" password="${tomcat.password}" /> </target> </project>
下面是構造文件在實際中運行時候的樣子:
%ant
Buildfile: build.xml
main:
[get] Getting: [url]http://localhost:8080/manager/deploy?[/url]
path=/deployment&war=file:////c:\ant\ch08\get\app/
BUILD SUCCESSFUL
Total time: 1 second
這是Tomcat輸出到deploy.txt中的文件內容:
OK - Deployed application at context path /deployment
在部署之後, 經過[url]http://localhost:8080/deployment/org.antbook.ch08.Deploy[/url]顯示出部署的servlet,如圖8-1。
圖 8-1. 部署到Tomcat
小技巧: 想要獲得Tomcat管理servlet上的更多的信息,查看Tomcat的manager/html-manager-howto.html。
get任務的屬性在表8-4列出.
表 8-4. get任務屬性
小技巧: 當verbose 被設置爲true的時候,任務會每接受100K顯示一個點(.)。
編譯JSPs
當部署到服務器時, jspc任務是頗有用的。 這個任務運行JavaServer Pages編譯器而且把JSP頁變成Java源代碼,也能夠在javac任務中實現。編譯JSP頁支持JSP網頁的快速調用, 在沒有徹底的JDK服務器上的部署, 或讓你不用部署就能夠檢查他們網頁的語法。 缺省狀況下,這個任務使用由Tomcat自帶的Jasper JSP編譯器。 拷貝Tomcat的jasper-compiler.jar和jasper-runtime.jar文件進Ant的lib目錄來使用這個任務。 你將須要在Ant lib目錄下放置由Tomcat帶來的servlet.jar。
例如, 你有這JSP頁面, greeting.jsp:
<HTML> <HEAD> <TITLE>Creating a Greeting</TITLE> </HEAD> <BODY> <H1>Creating a Greeting</H1> <% out.println("Hello from JSP!"); //Display the greeting %> </BODY> </HTML>
例子8-5顯示出怎麼編譯這JSP成greeting.java。
例子8-5 編譯JSP頁(ch08/jspc/build.xml)
<?xml version="1.0" ?> <project default="main"> <property name="message" value="Compiling the JSP...." /> <property name="src" location="source" /> <property name="output" location="bin" /> <target name="main" depends="init, compile"> <echo> ${message} </echo> </target> <target name="init"> <mkdir dir="${output}" /> </target> <target name="compile"> <jspc srcdir="${src}" destdir="${output}" package="org.antbook.jsp" verbose="9"> <include name="**/*.jsp" /> </jspc> </target> </project>
下面是你在運行構造文件時候所要看到的:
%ant
Buildfile: build.xml
init:
compile:
[jspc] Compiling 1 source file to
/home/steven/ant/ch08/jspc/bin/org/antbook/jsp
[jasperc] 2004-06-30 02:20:09 - Class name is:
greeting
[jasperc] 2004-06-30 02:20:09 - Java filename is:
/home/steven/ant/ch08/jspc/bin/org/antbook/jsp/greeting.java
[jasperc] 2004-06-30 02:20:09 - Accepted
org.apache.jasper.compiler.Parser$Scriptlet at /greeting.jsp(7,4)
[jasperc] 2004-06-30 02:20:09 - Compiling with: -encoding UTF8
main:
[echo]
[echo] Compiling the JSP....
[echo]
BUILD SUCCESSFUL
Total time: 3 seconds
下面是Java代碼結果greeting.java看起來的樣子:
package org.antbook.jsp.; import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;import org.apache.jasper.runtime.*; public class greeting extends HttpJspBase { static { } public greeting( ) { } private static boolean _jspx_inited = false; public final void _jspx_init( ) throws org.apache.jasper.runtime.JspException { } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; PageContext pageContext = null; HttpSession session = null; . . . out.println("Hello from JSP!"); //Display the greeting .. . }}
下面是另外一個例子,它編譯JSP頁,檢查相關性, 而且使用javac任務爲這JSP建立實際的bytecode:
<jspc destdir="temp" srcdir="${src}" package="org.antbook.ch08"> <include name="**/*.jsp" /></jspc> <depend srcdir="temp" destdir="${bin}" classpath="lib/app.jar"/> <javac srcdir="temp" destdir="${bin}" classpath="lib/app.jar" />
在表8-5你能看見jspc任務的屬性。
表 8-5. jspc任務的屬性
jspc任務是一個基於目錄的任務,所以被編的JSP文件用javac任務定位同樣的方法定位文件, 它意味着你能使用嵌套元素,例如includes 和 excludes。你能使用嵌套的classpath和classpathref元素, 象嵌套的webapp元素同樣。惟一出如今jspc任務中的webapp元素,指示JSP編譯器建立一個所有Web應用程序程序。一個webapp元素的屬性是basedir屬性, 它設置應用程序的根目錄。在它下級子目錄必須有一個WEB-INF子目錄。若是你使用這元素,這個任務使用編譯器檢查全部的相關性。
下面是一個使用webapp的例子:
<jspc package="org.antbook.ch08"> <include name="**/*.jsp" /> <webapp basedir="${ch08}" /></jspc>
部署至EJB 容器
基本上,部署JavaBean到企業(EJB) 應用服務器類似於你已經看見的另外的Ant部署工程。你能使用這任務來打包而且部署EJB應用。例如,在例子8-6你會看到一個爲JBoss服務器開發的構造文件; 構造文件首先創造一個.war文件而後把它打包進一個用來部署的.ear文件。
例8-6 一個Jboss EJB構造文件(ch08/ejb/build.xml)
<?xml version="1.0" ?><project default="main" basedir="."> <target name="main" depends="init, compile, war, ear"/> <target name="init"> <property name="src" value="${basedir}/src"/> <property name="bin" value="${basedir}/output"/> <property name="web" value="${basedir}/web"/> <property name="descriptors" value="${basedir}/output/deploymentdescriptors"/> <property name="eardir" value="${basedir}/output/ear"/> <property name="wardir" value="${basedir}/output/war"/> <property name="warfile" value="app.war"/> <property name="earfile" value="app.ear"/> <mkdir dir="${wardir}/WEB-INF"/> <mkdir dir="${wardir}/WEB-INF/classes"/> <mkdir dir="${eardir}/META-INF"/> </target> <target name="compile"> <javac destdir="${bin}" srcdir="${src}" includes="**/*.java" /> </target> <target name="war"> <copy todir="${wardir}"> <fileset dir="${web}" includes="**/*.*" /> </copy> <copy file="${descriptors}/web.xml" todir="${wardir}/WEB-INF" /> <copy todir="${wardir}/WEB-INF/classes"> <fileset dir="${bin}" includes="**/*.class" /> </copy> <jar jarfile="${eardir}/${warfile}" basedir="${wardir}" /> </target> <target name="ear"> <copy file="${descriptors}/application.xml" todir="${eardir}/META-INF" /> <jar jarfile="${basedir}/${earfile}" basedir="${eardir}" /> </target> </project>
這就是所有。儘管這構造文件使用標準的Ant任務工做,被構造了進Ant的任務使以ear任務開始的EJB應用程序工做更容易。
建立ear文件
創造ear任務是容易的.ear文件而且爲在大多數ear須要的application.xml文件作特殊的預備。
它沒有強制使用這個任務創造一個.ear文件,可是它能使生活更容易。
在表8-6你能看見這個任務的屬性。
小技巧: ear任務是一個有爲application.xml的特殊的待遇的對Jar任務的擴展。
你能夠進行同樣的操做,在一個zip或者jar任務中使用prefix(前綴)和fullpath屬性。
表8-6 ear任務的屬性
從zip任務的擴充的支持屬性 prefix, fullpath,和src的zipfileset元素,在ear任務也一樣能夠辦到。 嵌套的metainf元素規定一個fileset; fileset包括的全部的文件在.ear文件的META-INF目錄的結束。
這個任務容許你使用appxml屬性設定從什麼地方獲得application.xml。 下面是一個建立.ear文件的例子:
<ear destfile="${output}/app.ear" appxml="${src}/application.xml"> <fileset dir="${wardir}" includes="*.war"/></ear>
支持熱部署
serverdeploy任務被設計成支持熱部署 (在部署前你沒必要關閉服務器) 到EJB- aware的服務器。你設置action屬性爲你作見過的屬性,像爲Tomcat 管理器servlet設置使用了的那些: "deploy", "delete", 和 "undeploy"。
小技巧: 你可能須要vendor-specific來完成這個工做。
Ant提供build-end, 可是你的服務器須要提供Ant能連結與而且交往的一套部署工具。
在寫這篇文章時, 這個任務僅僅支持Weblogic服務器和JOnAS 2.4開放源代碼EJB服務器,可是對另外的EJB容器的支持應該快被增長。
這個任務有僅僅2屬性,在表8-7被列出, 而且要求一些嵌套元素。
表8-7 serverdeploy任務的屬性
generic元素
若是你從服務器生產商獲得Java類的部署代碼,這是一個用於基於Java的部署的通用元素。若是有一個廠家特定的元素給serverdeploy使用,那固然使用它;但若是沒有,那請使用通generic元素。
在表8-8此元素的屬性被列出。
表8-8 generic元素的屬性
generic元素支持嵌套的arg和jvmarg元素。下面是一個假定目標Web服務器是org.steven.j2ee.config.Deploy時,使用generic元素的部署文件的例子:
<serverdeploy action="deploy" source="${eardir}/app.ear"> <generic classname="org.steven.j2ee.config.Deploy" classpath="${classpath}" username="${user.name}" password="${user.password}"> <arg value="-install"/> <jvmarg value="-mx512m"/> </generic> </serverdeploy>
weblogic元素
weblogic元素用於運行weblogic.deploy部署工具; 此工具的合法的actions包括:deploy, undeploy, list, update, 和 delete.。
在表8-9這些元素的屬性被列出。
表8-9 weblogic元素的屬性
下面是一個使用這個serverdeploy元素內部的元素來部署WebLogic服務器的例子:
<serverdeploy action="deploy" source="${eardir}/app.ear"> <weblogic application="app" server="ff19://server:7001" classpath="${weblogic.home}/lib/weblogic.jar" username="${user.name}" password="${user.password}" component="appserver,productionserver" /></serverdeploy>
jonas元素
jonas單元支持部署到JOnAS (Java Open Application Server, Java開放應用服務器) 服務器。 JOnAS部署工具 (org.objectweb.jonas.adm.JonasAdmin) 的有效actions有
deploy, undeploy, list 和 update.
在表8-10這元素的這些屬性別列出。
表8-10。 jonas元素的屬性
小技巧: 若是你準備根據從服務器迴應的延期時間來編譯一個延期任務,使用Ant waitfor任務。 你可使用sleep任務來實現這個目的。
jonas單元支持嵌套的classpath, arg,和jvmarg單元。 下面是一個使用serverdeploy部署到一個JOnAS服務器的例子:
<serverdeploy action="deploy" source="${eardir}/app.jar"> <jonas server="JOnAS5" jonasroot="${jonas.root}"> <classpath> <pathelement path="${jonas.root}/lib/RMI_jonas.jar"/> </classpath> </jonas></serverdeploy>
Steve Holzner是O'Reilly出版的 upcoming Eclipse: A Java Developer's Guide的做者。