This article contains a set of
Ant scripts that will allow you to fully automate your build & deployment in one single operation.
The technologies involved Ant, CVS, and WebSphere.
The scenario is you run the scripts from your pc client and it will do the build in your pc, distribute the artifacts to a remote Unix environment, deploy the artifacts in Unix, and install the war application in WebSphere. You can optionally backout the entire installation.
This is a complete working set of scripts. You can copy/paste the scripts literally or modify the application via properties to suit your needs.
The following files are used:
1. main.xml
2. build.xml
3. dist.xml
4. deploy.xml
5. install.xml
6. project.properties
7. deploy.properties
To execute, the first and the only step is:
ant -buildfile main.xml
The following shows the complete listing of the files:
=======================================================
main.xml
=======================================================
<?xml version="1.0"?>
<!-- Ludwin Barbin 2009-07-24 -->
<project name="Main" default="main">
<tstamp/>
<property file="project.properties"/>
<property file="deploy.properties"/>
<!-- Main delegator -->
<target name="main" depends="build, full.deploy"/>
<!-- Build application -->
<target name="build">
<ant antfile="build.xml" target="build"/>
</target>
<!-- Full deploy application -->
<target name="full.deploy" depends="dist, backup, deploy, install, cleanup"/>
<!-- Distribute Files -->
<target name="dist" depends="dist.web, dist.was"/>
<target name="dist.web">
<ant antfile="dist.xml" target="dist.web"/>
</target>
<target name="dist.was">
<ant antfile="dist.xml" target="dist.was"/>
</target>
<!-- Backup Files -->
<target name="backup" depends="backup.web, backup.was"/>
<target name="backup.web">
<sshexec host="${web.host}" username="${web.userId}" password="${web.password}" command="${web.ant.deploy} backup.web" trust="true"/>
</target>
<target name="backup.was">
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.deploy} backup.was" trust="true"/>
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.install} export.app" trust="true" />
</target>
<!-- Deploy Files -->
<target name="deploy" depends="deploy.web, deploy.was"/>
<target name="deploy.web">
<sshexec host="${web.host}" username="${web.userId}" password="${web.password}" command="${web.ant.deploy} deploy.web" trust="true"/>
</target>
<target name="deploy.was">
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.deploy} deploy.was" trust="true"/>
</target>
<!-- Install application to WebSphere -->
<target name="install">
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.install} install" trust="true" />
</target>
<!-- Cleanup Files -->
<target name="cleanup" depends="clean.unix, clean.loc" />
<target name="clean.unix">
<sshexec host="${web.host}" username="${web.userId}" password="${web.password}" command="rm -rf ${web.tmp.dir}" trust="true"/>
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="rm -rf ${was.tmp.dir}" trust="true"/>
</target>
<target name="clean.loc">
<delete dir="${src.dir}"/>
<delete dir="${classes.dir}"/>
<delete dir="${build.dir}"/>
</target>
<!-- Backout Files if deployment fails -->
<target name="backout" depends="backout.web, backout.was"/>
<target name="backout.web">
<sshexec host="${web.host}" username="${web.userId}" password="${web.password}" command="${web.ant.deploy} backout.web" trust="true"/>
</target>
<target name="backout.was">
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.deploy} backout.was" trust="true"/>
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" command="${was.ant.install} backout" trust="true" />
</target>
</project>
==========================================================
build.xml
==========================================================
<?xml version="1.0"?>
<!-- Ludwin Barbin 2009-07-24 -->
<project name="Build" default="build">
<tstamp/>
<property file="project.properties"/>
<path id="app.classpath">
<fileset dir="${lib.dir}"/>
<fileset dir="${web.dir}/WEB-INF/lib"/>
<dirset dir="${classes.dir}"/>
</path>
<!-- call the build steps -->
<target name="build" depends="clean, checkout, compile, package"/>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${src.dir}"/>
<delete dir="${classes.dir}"/>
<mkdir dir="${build.dir}"/>
<mkdir dir="${src.dir}"/>
<mkdir dir="${classes.dir}"/>
</target>
<target name="checkout">
<cvs cvsRoot="${cvs.root}" package="${main.project}" dest="${src.dir}" reallyquiet="true" failonerror="true"/>
</target>
<target name="compile">
<javac srcdir ="${src.dir}/${main.project}" destdir ="${classes.dir}" classpathref="app.classpath"/>
</target>
<target name="package">
<!-- package war file -->
<war destfile="${build.dir}/${app.war}" webxml="${web.dir}/WEB-INF/web.xml">
<classes dir="${classes.dir}"/>
<fileset dir="${web.dir}"/>
</war>
<!-- package web files -->
<tar destfile="${build.dir}/${app.web.tar}">
<tarfileset dir="${web.root.dir}" />
</tar>
<!-- package was files -->
<tar destfile="${build.dir}/${app.was.tar}">
<tarfileset dir="${was.root.dir}"/>
</tar>
</target>
</project>
=======================================================
dist.xml
=======================================================
<?xml version="1.0"?>
<!-- Ludwin Barbin 2009-07-24 -->
<project name="Distribute">
<tstamp/>
<property file="project.properties"/>
<property file="deploy.properties"/>
<target name="dist.web">
<!-- create temp directory for distribution -->
<sshexec host="${web.host}" username="${web.userId}" password="${web.password}" trust="true"
command="rm -rf ${web.tmp.dir}; mkdir ${web.tmp.dir}"/>
<scp todir="${web.userId}:${web.password}@${web.host}:${web.tmp.dir}" trust="true">
<fileset dir="${build.dir}">
<include name="${app.web.tar}"/>
</fileset>
<fileset dir="${basedir}">
<include name="deploy.xml"/>
<include name="project.properties"/>
<include name="deploy.properties"/>
</fileset>
</scp>
</target>
<target name="dist.was">
<!-- create temp directory for distribution -->
<sshexec host="${was.host}" username="${was.userId}" password="${was.password}" trust="true"
command="rm -rf ${was.tmp.dir}; mkdir ${was.tmp.dir}"/>
<scp todir="${was.userId}:${was.password}@${was.host}:${was.tmp.dir}" trust="true" >
<fileset dir="${build.dir}">
<include name="${app.war}"/>
<include name="${app.was.tar}"/>
</fileset>
<fileset dir="${basedir}">
<include name="deploy.xml"/>
<include name="install.xml"/>
<include name="project.properties"/>
<include name="deploy.properties"/>
</fileset>
</scp>
</target>
</project>
=========================================================
deploy.xml
=========================================================
<?xml version="1.0"?>
<!-- Ludwin Barbin 2009-07-24 -->
<project name="Deploy">
<tstamp/>
<property file="project.properties"/>
<property file="deploy.properties"/>
<target name="backup.web">
<tar basedir="${web.app.dir}" destfile="${web.archive.dir}/${app.web.bkup.tar}" />
</target>
<target name="backup.was">
<tar basedir="${was.app.dir}" destfile="${was.archive.dir}/${app.was.bkup.tar}" />
</target>
<target name="deploy.web" depends="clean.web">
<untar src="${basedir}/${app.web.tar}" dest="${web.app.dir}"/>
</target>
<target name="deploy.was" depends="clean.was">
<untar src="${basedir}/${app.was.tar}" dest="${was.app.dir}"/>
</target>
<target name="backout.web" depends="clean.web">
<untar src="${web.archive.dir}/${app.web.bkup.tar}" dest="${web.app.dir}"/>
</target>
<target name="backout.was" depends="clean.was">
<untar src="${was.archive.dir}/${app.was.bkup.tar}" dest="${was.app.dir}"/>
</target>
<target name="clean.web">
<delete includeemptydirs="true"> <fileset dir="${web.app.dir}" includes="**/*"/> </delete>
</target>
<target name="clean.was">
<delete includeemptydirs="true"> <fileset dir="${was.app.dir}" includes="**/*"/> </delete>
</target>
</project>
==========================================================
install.xml
==========================================================
<?xml version="1.0"?>
<!-- Ludwin Barbin 2009-07-24 -->
<project name="Install" >
<tstamp/>
<property file="project.properties"/>
<property file="deploy.properties"/>
<!-- WebSphere tasks -->
<taskdef name="wsadmin" classname="com.ibm.websphere.ant.tasks.WsAdmin"/>
<taskdef name="wsStopServer" classname="com.ibm.websphere.ant.tasks.StopServer"/>
<taskdef name="wsStartServer" classname="com.ibm.websphere.ant.tasks.StartServer"/>
<taskdef name="wsStopApp" classname="com.ibm.websphere.ant.tasks.StopApplication"/>
<taskdef name="wsStartApp" classname="com.ibm.websphere.ant.tasks.StartApplication"/>
<taskdef name="wsUninstallApp" classname="com.ibm.websphere.ant.tasks.UninstallApplication"/>
<taskdef name="wsInstallApp" classname="com.ibm.websphere.ant.tasks.InstallApplication"/>
<!-- delegator -->
<target name="install" depends="stop.server, uninstall.app, install.app, start.server" />
<target name="stop.server"> <wsadmin command="$AdminControl stopServer ${was.server} ${was.node}"/> </target>
<target name="start.server"><wsadmin command="$AdminControl startServer ${was.server} ${was.node}" failonerror="true"/> </target>
<target name="start.app"> <wsStartApp server="${was.server}" application="${app.name}" failonerror="true"/> </target>
<target name="stop.app"> <wsStopApp server="${was.server}" application="${app.name}"/> </target>
<target name="install.app"> <wsInstallApp ear="${was.tmp.dir}/${app.war}" options="{${was.install.options}}" failonerror="true"/> </target>
<target name="uninstall.app"> <wsUninstallApp application="${app.name}"/> </target>
<target name="export.app">
<wsadmin command="$AdminApp export ${app.name} ${was.archive.dir}/${app.bkup.ear}" failonerror="true"/>
</target>
<target name="backout" depends="stop.server, uninstall.app, reinstall.app, start.server" />
<target name="reinstall.app"> <wsInstallApp ear="${was.archive.dir}/${app.bkup.ear}" options="{${was.install.options}}" failonerror="true"/> </target>
</project>
-------------------------------------------------------
project.properties
-------------------------------------------------------
# Ludwin Barbin 2009-07-24
# === CVS properties ================================
main.project =myproject
cvs.root =:pserver:anonymous:anonymous@my.cvs.com:/myrepository
# === directories ==================================
lib.dir =${basedir}/lib
src.dir =${basedir}/src
classes.dir =${basedir}/classes
build.dir =${basedir}/build
web.dir =${src.dir}/${main.project}/WebContent
web.root.dir =${src.dir}/${main.project}/web_root
was.root.dir =${src.dir}/${main.project}/was_root
# === archive filenames ===============================
app.war =app.war
app.web.tar =app-web.tar
app.was.tar =app-was.tar
app.web.bkup.tar =app-web-bkup-${DSTAMP}.tar
app.was.bkup.tar =app-was-bkup-${DSTAMP}.tar
app.bkup.ear =app-bkup-${DSTAMP}.ear
-------------------------------------------------------
deploy.properties
-------------------------------------------------------
# Ludwin Barbin 2009-07-24
# ============= UNIX directories =================
# In Web
web.app.dir =/apps/myapp
web.archive.dir =/apps/myapp-archive
web.tmp.dir =${web.archive.dir}/tmp
# In WAS
was.app.dir =/apps/myapp
was.archive.dir =/apps/myapp-archive
was.tmp.dir =${was.archive.dir}/tmp
was.bin.dir =/apps/WebSphere/bin
# ============= Login properties =================
web.host =mywebhost
web.userId =webid
web.password =web123
was.host =mywashost
was.userId =wasid
was.password =was123
# ============= Ant execution properties =================
web.ant.deploy =ant -buildfile ${web.tmp.dir}/deploy.xml
was.ant.deploy =ant -buildfile ${was.tmp.dir}/deploy.xml
was.ant.install =sudo -s ${was.bin.dir}/ws_ant.sh -buildfile ${was.tmp.dir}/install.xml
web.ant.version =ant -version
was.ant.version =ant -version
was.wsant.version =${was.bin.dir}/ws_ant.sh -version
# === WebSphere server properties ===============================
was.cell =mywascell
was.node =mywasnode
was.server =mywasserver
# ================ Installation options properties ========================
app.name =myapp
context.root =/myapp
was.install.options =-cell ${was.cell} -node ${was.node} -server ${was.server} -contextroot ${context.root} -appname ${app.name}
-- End of files --
Feel free to use the code in your project. This is especially useful in Development environment where a quick deployment is essential.
The benefits of having an automated build & deployment is very applicable when using Agile development. It allows you quickly see your changes, get feedback, and adapt accordingly.
If you have a way of improving the code, let me know. I am not an expert in Ant but I've used the above scripts in my projects and it helped our development team a lot.