Tomcat教程

Apache Ant自动化部署

如果要周期性地改变Web应用程序,并不得不经常执行这些不同的部署步骤,则会想要让过程自动化,而非每次都要重新输入jar(或许还有copy/cp)命令。本节会教您如何使用Ant。这是Apache Software Foundation (Apache软件基金会)的构建(build)工具。您也可以使用任何喜爱的工具——诸如make, Perl, shell脚本或批处理文件。不过,在Java与Tomcat社区中,Ant已渐渐成为自动部署的标准工具,所以最妤能对Ant有基础的认识。

Ant会自动执行其他的程序,更精确地说,Ant可以运行非Java程序。它可以执行非Java的程序,不过仅只是执行Java类,就因能处理许多事情而获益。因为Ant是以Java编写的,而且有可靠的JVM,因此执行其他的Java功能(包括Java编译器)会相当快速,因为JVM已相当盛行。Ant也含有执行一般操作的内嵌任务的庞大链接库,包括处理TAR,JAR,ZIP,GZIP及其他文件格式,而且通常不諸执行外部程序。也就是说,它含有能读/写 这些及其他格式文件、复制文件和编译Java程序(包括servkt)等的OS便携式Java类。

Ant会读入以XML编写的构建(build)文件,以找寻要执行的命令,而一般的文件名则为build.xml。Ant的构建文件包含一个项目定义,以及许多目标(target;类似于子程序),其中一个是默认的目标。目标是一个类似于如何处理下列事情的工作单位, 编译某些servlet、构建JAR文件或复制JAR文件。在Ani的命令上,您可以用名字执行任何目标,如果不提供目标名称,则默认目标是run。每个目标都可以包含任务,而任务初略地类似于单独的命令。

构建 JAR/WAR

Ant有处理JAR/WAR文件,及复制文件的嵌人式任务。示例3-2是Web应用程序中的一个build.xml示例,只是在用干此处时作了一些轻微的裁减。

示例3-2:可产生WAR文件的Ant构建文件(build.xml)

<project name="Hello World Web Site" 
      default="war 
      basedir=".">
			
<!—构建WAR文件-->
 <target name="war"
  description="Builds the WAR file.">
<war destfile="${deploy.war}"
       webxml="${basedir}/Webapp-dir/WEB-INF/web.xml" 
      basedir="${basedir}/webapp-dir"
     excludes="WEB-INF/**/*">
<lib dir="${basedir}/webapp-dir/WEB-INF/lib"/>
<webinf dir="${basedir}/webapp-dir/WEB-INF"
	   excludes="web.xml"/>
<metainf dir="${basedir}/webapp-dir/META-lNF"/>
</war>
</target>
</project>

请注意war Ant任务怎样创建WAR文件。笔者在打包文件中使用了webxml属性,并给合提供WEB-INF/web.xml文件的路径,然后让它包含了Web应用程序的basedir下的所有文件,并设置为${basedir}/webapp-dir。笔者还告诉Ant,在哪里能找到这个特殊对待的WEB-INF目录,这个目录很特殊,它虽然没有包含服务于客户端的文件,但仍 然组成了Web应用程序代码和配置文件。但是,笔者不想在该打包文件中再包含WEB-INF/web.xml因为这会让Ant误认为笔者想两次包含web.xml。因此,笔者进行了excludes="WEB-INF/**/*"属性设置。双星号(**)意味着映射所有目录路径,由此推断,这一设置排斥了属性设置并让Ant不包含WEB-INF树中的内容。这是笔者预期的内 容,因为webinf元素巳经包含了减去web.xml/文件(这已通过webxml属性 进行了特殊处理)。


通过Ant进行部署

通过ANT编译工具部属Web应用程序的方法有多种:

复制Web应用程序到本地Tomcat安装的部署目录中
只复制Web应用程序的解包目录或WAR文件到已配置好的Tomcat Host appBase目录(如CATALINA_HOME/webapp)下,然后根据已配置的Host,有选择地重启Tomcat。这是Ant可轻松完成的事情,只要执行一个<copy>。

使用Manag以Web应用程序,通过网络^远程”部署Web应用程序
Ant可以通过HTTP使您与Manager Web应用程序交互。Tomcat提供的定制Ant任务,给您与Tomcat的Manager Web应用程序提供了一个很好的可编程Ant接口。如果Tomcat与Ant运行在同一台机器上,则可以实现本地化,如果Tomcat与Ant运行 在不同的机器上,则可以实现远程化。无论是哪种方式,Ant都使用了网络,通过 HTTP给Tomcat发送命令。

使用Tomcat的独立部署器
Tomcat有一个独立部署器,它实际是一个目录,该目录包含了通过HTTP给 Manager Web应用程序提供命令的Ant编泽工具和所有必要的JAR文件。

使用Ant的scp(Secure CoPy)任务 Ant能在网络上通过scp Ant任务远程复制文件。您需要完成的任务只是增加一个启用scp让任务的JAR文件,然后编写一个该任务使用的Ant编译文件。这一方法可用于远程或本地安装的Tomcat,只要远程复制的目的机器正运行了一个非Windows操作 系统上都有的SSH (Secure SHell)后台程序就可以了。


复制WAR文件或Web应用程序目录

通过Ant进行部署的最简便的方法足Tomcat与Ant正运行在同一台机器上的情况,一旦已经建立Web应用程序,您就可以编写在网络上复制Web应用程序到Tomcat中的编译文件 记住:不要仅复制Web应用程序,而不为您正处理的事情配置Tomcau在本章前面, 笔者复习了Tomcat支持的各种部署方法及存在的问题。您大概想复制Web应用程序和 context XML片段文件,这要依您要将Web应用程序映射的URI和如何配置Host而定。 示例3-3是示例3-2编译文件的扩展版本,但这-版本也把文件复制到Tomcat的部署目录中。

示例3-3:编译和部署WAR文件的Ant脚本

<project name=nHello World Web Site" 
        default="war"
        basedir=".">
        
<!--在此处存储"常量"便于修改-->
<property name="deploy.dir"
         value=/opt/tomcat/webapps"/>
<propeity name="deploy.war" value=/tmp/hello.war"/>

<!--编译WAR文件-->
<target name="war"
 description="Builds the WAR file.">
<war destfile=${deploy.war}"
webxml = "${ basedir}/webapp-dir/WEB-INF/web.xml"
basedir="${basedir}/webapp-dir"
excludes="WEB-lNF/**/*">
<lib dir="${basedir}/webapp-dir/WEB-INF/lib"/>
<webinf dir="${basedir}/webapp-dir/WEB-INF" 
	excludes="web.xml"/>
<metainf dir="${basedir}/webapp-dir/META-INF"/>
</war>
</target>

<!--复制WAR到Toncat的部署目录中-->
<target name="deploy" depends="war"
 description="Deploys the WAR file locally.">
<copy file="${deploy,war}" todir="${deploy.dir}"/>
</target>
</project>

如果运行版本2,则它以相同方式产生WAR文件。然后可以测试这个WAR文件(使用命令行解包工具)。然后,重新调用Ant,对Web应用稈序进行本地部署。整个会话过程展现在示例3-4中。

示例3-4:使用Ant编译和部署该WAR文件

ian$ ant
Buildfile:build.xml

     [jar] Building jar: /tmp/hello.war
     
BUILD SUCCESSFUL
Total time: 2 seconds
ian$ $ unzip -t /tmp/hello.war
Archive: /tmp/hello.war
   testing: meta-inf/	OK
   testing: META-INF/MANIFEST.MF	OK
   testing: WEB-INF/	OK
   testing: WEB-INF/classes/	OK
   testing: /upload/image/course/tomcat/	OK
   testing: WEB-INF/web.xml	OK
   testing: index.jsp	OK
   testing:/upload/image/course/tomcat/logo.png	OK
   testing: build.xml	OK 
   testing: ListParametersForm.html OK
   testing: play.html	OK
   testing: jspIncludeCGI.jsp	OK
在压缩的数据包/tmp/hello.war中没检测到错误。 
ian$ sudo ant deploy 
Buildfile: build.xml

war:

deploy:
     [copy] Copying 1 file to /opt/tomcat/webapps
BUILD SUCCESSFUL 
Total time: 2 seconds
ian$

访问Manager Web应用程序

Manager Web应用程序的所有任务都可以通过Ant进行自动访问。

因为这些Ant任务实际使用了Manager Web应用程序,所以必须提前设置好一个用户名与口令,组合在Tomcat领域中,并允许成为管理员角色。

然后,需要更新Ant的build.xml文件,以提供从任务名到Java类的映射,实现Tomcat的Ant任务,您可以将这Ant配置增加到build.xml文件中。表3-1列出了Tomcat的Catalina Ant任务。

表3-1: Tomcat Catalina Ant任务

任务名Java类名描述
deployorg.apache.catalina.ant.DeployTask部署Web应用程序
listorg.apache.catalina.ant.ListTask列出当前部署的所有Web应用程序
reloadorg.apache.catalina.ant.ReloadTask重新加载Web应用程序
sessionsorg.apache.catalina.ant.SessionsTask列出给定的Web应用程序的所有现行会话
resourcesorg.apache.catalina.ant.ResourcesTask列出所有全局JNDI资源
rolesorg.apache.catalina.ant.RolesTask列出 Tomcat 的所有安全角色
startorg.apache.catalina.ant.StartTask启动一个Web应用程序
stoporg.apache.catalina.ant.StopTask停止一个 Web 应用程序
undeployorg.apache.catalina.ant.UndeployTask解除一个Web应用程序的部署
validatororg.apache.catalina.ant.ValidatorTask使本地文件系统上的一个web.xml文件生效
jmxsetorg.apache.catalina.ant.JMXSetTask设置一个Tomcat Mbean的JMX属性值
jmxsetorg.apache.catalina.ant.JMXSetTask得到一个Tomcat Mbean的JMX属性值
jmxqueryorg.apache.catalina.ant.JMXQueryTask査询Tomcat Mbean

示例3-5的build.xml文件可以构造该WAR文件,将它部署到Tomcat中(使用Tomcat的安 装任务),然后列出现行部署的所有Web应用程序(使用Tomcat的列表任务)。

示例3-5: build.xml使用Tomcat的 Ant任务

<project name="Hello World Webapp" default="war" 
						basedir=".">
<!--将该编译文件指向Tomcat安装目录-->
<property name=”catalina.home" value="/opt/tomcat"/>
	
<!--在只有自己设定的用户可以读的独立文件中存储用户名和口令-->
<property file="user-pass.properties"/>
	
<property name="deploy.dir"
         value="/opt/tomcat/webapps"/>
<property name="deploy.war" values="/tmp/hello.war"/>

<!--设置context路径-->
(property name="path" value="/hello"/>

<!--访问Manager Web应用程序的属性-->
<property name="manager.url"
         value=http://localhost:8080/manager"/>
         
<path id="tomcat.lib.classpath>
<fileset dir="${catalina.home}/bin">
<include name="*.jar"/>
</fileset>
<fileset dir="${catalina.home}/lib">
<include name="*.jar"/>
</fileset>
</path>
<!--给Manager Web应用程序紀置自定义任务-->
<taskdef
resource="org/apache/catalina/ant/catalina.tasks" 
classpathref="tomcat.lib.classpath"/>
<!-- 编译war文件 -->
<target name="war">
<war destfile="${deploy.war}"
Webxml="${basedir}/webapp-dir/WEB-INF/web.xml" 
basedir="${basedir}/webapp-dir" 
excludes="WEB-INF/**/*">
<lib dir="${basedir}/webapp-dir/WEB-INF/lib"/>
<webinf dir="${basedir}/webapp-dir/WEB-INF"
excludes="web,xml"/>
<metainf dir="${basedir}/webapp-dir/META-INF"/>
</war>
</target>
<!--部署新的web应用程序-->
<target name="deploy" depends="war"
descriptions="Deploys the webapp.">
<deploy url="${manager.url}"
	 username="${user}"
	 password="${pass}" 
	     path="${path}" 
	     war="file://$ {deploy.war}"/>
</target>

<!--重载该web应用程序-->
<target name="reload" depends="war"
 description="Reloads the webapp.">
<reload url="${manager.url}" 
	 userrame="${user}" 
	 password="${pass}" 
	 path="${path}"/>
</target>

<!--获得所有web应用程序的状态-->
<target name="list"
  description="Lists all running webapp."<
<list url="${manager.url}" 
 username="${user}" 
 password="${pass}"/>
</target>

<target name="clean"
 desctiption="Cleans the builds.">
<delete file="${deploy.war}"/>
</target>

</project>

文件是一个Java属性文件,所以笔者使用Ant的属性任务,在该文件中包含了一个文件属性。这使Ant读取该属性文件,然后在Ant JVM中设置该属性文件的 所有属性,从而使这些设置可用于编译。 出于安全防护需要,您如果坚持要在命令行上指定口令,而不是让它留在文件中,那么您可以在该文件中放置一个虚拟口令(或者完全省略),然后使用下列内容在运行时指定口令:

$ ant-Dpassword=deep_dark_secret deploy

为触发重载,尝试:

ian$ ant reload
Buildfile: build.xml
Mar:
[jar] Building jar: /tmp/hello.war 

reload:
[reload] OK - Reloaded application at context path /hello

BUILD SUCCESSFUL 
Total time: 3 seconds

注意在完成这一工作时,Ant使用了网络连接到Tomcat的Web服务器,告泝Tomcat要重 新加载该Web应用程序。如果您已为Manager Web应用程序止确设置了用户名和口令, 且假设在Ant和Tomcat之间没有防火墙,则运行正常,否则会阻塞HTTP连接。

用这种方式修改Web应用程序的如文件,远程使用Manager Web应用程序,是笔者 建议您通过Ant部署Web应用程序的方法,即使您的Tomcat在同一台机器上,也是如此。 这是因为与只复制文件相比,Ant更能根据您控制的需要,以多种方式控制Tomcat。还有一个原因就是,这一部署方法在本地部署和远程部署中都能生效。

关注微信获取最新动态