<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sheila&#039;s Blog &#187; build</title>
	<atom:link href="http://sheilapollard.com/category/build/feed/" rel="self" type="application/rss+xml" />
	<link>http://sheilapollard.com</link>
	<description>Software Development</description>
	<lastBuildDate>Wed, 24 Mar 2010 17:19:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Setting up an Automated Build System</title>
		<link>http://sheilapollard.com/2009/06/09/setting-up-an-automated-build-system/?utm_campaign=feed&utm_medium=feed&utm_source=blog</link>
		<comments>http://sheilapollard.com/2009/06/09/setting-up-an-automated-build-system/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 10:04:43 +0000</pubDate>
		<dc:creator>Sheila</dc:creator>
				<category><![CDATA[build]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://sheilapollard.wordpress.com/?p=430</guid>
		<description><![CDATA[Many teams apply continuous integration as part of their software development process.  This means that each team member integrates their work regularly.  To facilitate doing this, you first need an automated build script that each developer can use to compile and build the code locally.  If there are no issues, then the developer can check [...]]]></description>
			<content:encoded><![CDATA[<p>Many teams apply continuous integration as part of their software development process.  This means that each team member integrates their work regularly.  To facilitate doing this, you first need an automated build script that each developer can use to compile and build the code locally.  If there are no issues, then the developer can check in their code.  At this point you want an automated build system that takes the latest code from source control and builds it, notifying the team if there are any errors.  The advantage of such an automated build system is that teams are notified early on if there are any integration issues rather than just before a  release deadline.  The build machine also serves as a fully deployed example of the latest version.  When a team member says that a piece of work is completed it should be verified on this machine &#8211; not their own.</p>
<p><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2NydWlzZWNvbnRyb2wuc291cmNlZm9yZ2UubmV0Lw==" target=\"_blank\">Cruisecontrol</a> is an open source continuous integration tool.  It allows you to monitor a project, building it when files are updated and notifying you if any part of the build process fails.  There are a lot of reporting tools that can be run on your build.  Unit tests, cover coverage and analysis tools and java documentation are useful to add to your build and make available in your reporting application.  These can be integrated into cruisecontrol.</p>
<p>This post assumes that you are installing cruisecontrol on a redhat machine and that you deploy your application to JBoss.  Any necessary databases have been installed and configured, and you have an ant build script for building and deploying the application.  You have also created a user called cruise that will run the automated build.</p>
<p><strong>Install Java</strong><br />
Download jdk-6u13-linux-i586.bin to /home/cruise<br />
Type sh jdk-6u13-linux-i586.bin<br />
Accept the license agreement<br />
Java will install into the cruise home directory<br />
JAVA_HOME = /home/cruise/jdk1.6.0_13</p>
<p><strong>Install JBoss</strong><br />
Download jboss-4.2.2.GA.zip to /home/cruise<br />
unzip jboss-4.2.2.GA.zip<br />
To avoid any permgen memory errors edit JBOSS_HOME/bin/run.conf and set the following Xms, Xmx, PermSize and MaxPermSize values
<code&gt;JAVA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512 -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000"&lt;/code></p>
<p><strong>Install Ant</strong><br />
Download apache-ant-1.7.1-bin.tar.gz to /home/cruise<br />
gunzip apache-ant-1.7.1-bin.tar.gz<br />
tar -xvf  apache-ant-1.7.1-bin.tar</p>
<p><strong>Configure paths and settings for the user</strong><br />
You need to configure the .bashrc for the cruise user (assuming the user shell is bash)<code># .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
  . /etc/bashrc
fi

# User specific aliases and functions
export JAVA_HOME=/home/cruise/jdk1.6.0_13
export ANT_HOME=/home/cruise/apache-ant-1.7.1
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export JBOSS_HOME=/home/cruise/jboss-4.2.2.GA

export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$ORACLE_HOME/bin:$JBOSS_HOME/bin:$PATH</code><br />
<strong>Install subversion</strong><br />
Subversion should already be available, check this by running 'rpm -q subversion'<br />
and making sure it returns a value</p>
<p><strong>Install cruisecontrol</strong><br />
Download cruisecontrol-src-2.8.2.zip to /home/cruise<br />
unzip cruisecontrol-src-2.8.2.zip<br />
Type ant in /home/cruise/cruisecontrol-2.8.2/main</p>
<p><strong>Configure the build projects</strong><br />
mkdir /home/cruise/build<br />
mkdir /home/cruise/build/artifacts<br />
mkdir /home/cruise/build/logs<br />
mkdir /home/cruise/build/projects</p>
<p><strong>Configure a new project</strong><br />
For a project called 'projectname', in /home/cruise/build/projects/projectname you should check out the source code eg.<br />
svn checkout http://svn.company.com/project/trunk<br />
Configure the project settings and test the build script to verify that it works without errors.</p>
<p><strong>Configure CruiseControl</strong><br />
You will need to create a file called build-projectname.xml
<code>&lt;!-- Delegating build script, used by cruisecontrol to build the project.
Note that the basedir is set to the checked out project --&gt;
&lt;project name="build-projectname"
default="automatedbuild"
basedir="/home/cruise/build/projects/projectname"&gt;
  &lt;target name="automatedbuild"&gt;
    &lt;!-- Get the latest from SVN --&gt;
    &lt;exec executable="svn"&gt;
      &lt;arg line="up --username user --password pass"/&gt;
    &lt;/exec&gt;
    &lt;!-- Call the target that does everything --&gt;
    &lt;ant antfile="build.xml" target="clean-deploy"/&gt;
  &lt;/target&gt;
&lt;/project&gt;</code></p>
<p>Edit this file to match your own settings and set the correct username/password for subversion.</p>
<p>Now you need to create the config.xml that is used by cruisecontrol:
<code>&lt;cruisecontrol&gt;
&lt;!-- Schedule each project to check for modifications every 15 mins and build if modifications have been made --&gt;

&lt;project name="projectname" buildafterfailed="true" requiremodification="true"&gt;
  &lt;plugin name="svn" classname="net.sourceforge.cruisecontrol.sourcecontrols.SVN"/&gt;
    &lt;listeners&gt;
      &lt;currentbuildstatuslistener file="logs/projectname/status.txt"/&gt;
    &lt;/listeners&gt;
    &lt;modificationset quietperiod="180" ignoreFiles="*/projectname/db/**"&gt;
      &lt;svn localworkingcopy="projects/projectname"/&gt;
    &lt;/modificationset&gt;
    &lt;schedule interval="900"&gt;
    &lt;ant anthome="/home/cruise/apache-ant-1.7.1"
buildfile="build-projectname.xml"
target="automatedbuild"
uselogger="true"
usedebug="false"/&gt;
     &lt;/schedule&gt;
    &lt;log logdir="logs/projectname"&gt;
      &lt;delete every="1" unit="MONTH"/&gt;
      &lt;merge dir="projects/projectname/reports/junit/"/&gt;
      &lt;merge file="projects/projectname/reports/checkstyle/cs_errors.xml"/&gt;
      &lt;merge dir="projects/projectname/reports/metrics/"/&gt;
      &lt;merge dir="projects/projectname/reports/cobertura/"/&gt;
    &lt;/log&gt;
  &lt;publishers&gt;
  &lt;htmlemail mailhost="xxx.xxx.x.x"
username="emailuser"
password="emailpass"
returnname="CruiseControl"
returnaddress="&lt;em&gt;user@company.com&lt;/em&gt;"
reportsuccess="always"
subjectprefix="CruiseControl: Projectname - "
buildresultsurl="http://xxx.xxx.x.x:8080/cruisecontrol/buildresults/projectname"
skipusers="true" spamwhilebroken="false"
logdir="logs/projectname"
xsldir="/home/cruise/cruisecontrol-2.8.2/reporting/jsp/webcontent/xsl"
css="/home/cruise/cruisecontrol-2.8.2/reporting/jsp/webcontent/css/cruisecontrol.css"&gt;
&lt;always address="user@company.com" /&gt;
&lt;failure address="teamlist@company.com" reportWhenFixed="true"/&gt;
  &lt;/htmlemail&gt;

&lt;/publishers&gt;

&lt;/project&gt;

&lt;/cruisecontrol&gt;</code></p>
<p>Edit this again to suit your own settings.  Refer back to the cruisecontrol documentation for further information on the settings above, but this will check for updates to the source code every 15 mins.  If there are changes then the build will be run.  If the build fails then the team is emailed.  If it's successful then someone who monitors the build system can be emailed.</p>
<p><strong>Start CruiseControl</strong></p>
<p>To test the cruisecontrol configuration you need to execute cruisecontrol.sh from /home/cruise/build<br />
First set the permissions with chmod a+x /home/cruise/cruisecontrol-2.8.2/main/bin/cruisecontrol.sh<br />
Then run<br />
/home/cruise/cruisecontrol-2.8.2/main/bin/cruisecontrol.sh</p>
<p><strong>Configure Reporting</strong><br />
Type ant in<br />
/home/cruise/cruisecontrol-2.8.2/reporting/jsp</p>
<p>You will be asked for these parameters:<br />
log.dir: /home/cruise/build/logs<br />
status.file: status.txt<br />
artifacts.dir: /home/cruise/build/artifacts</p>
<p>Copy /home/cruise/cruisecontrol-2.8.2/reporting/jsp/dist/cruisecontrol.war to the jboss deploy directory</p>
<p>Start up jboss and you should be able to access cruisecontrol at http://<em>xxx.xxx.x.x</em>:8080/cruisecontrol/</p>
<br /><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQud29yZHByZXNzLmNvbS8/cD00MzAjY29tbWVudHM=" title=\"Comments on &quot;Setting up an Automated Build System&quot;\"><img src="http://sheilapollard.com/wp-content/plugins/feed-comments-number/image.php?430" alt="Comments" /></a> <img src="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?view=1&post_id=430" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://sheilapollard.com/2009/06/09/setting-up-an-automated-build-system/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automated Build &#8211; Mysql database scripts</title>
		<link>http://sheilapollard.com/2009/03/30/automated-build-mysql-database-scripts/?utm_campaign=feed&utm_medium=feed&utm_source=blog</link>
		<comments>http://sheilapollard.com/2009/03/30/automated-build-mysql-database-scripts/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 10:07:31 +0000</pubDate>
		<dc:creator>Sheila</dc:creator>
				<category><![CDATA[build]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[automated build]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://sheilapollard.wordpress.com/?p=202</guid>
		<description><![CDATA[Having set up the basic folder structure in Automated Build Databse scripts you now need to add the mysql scripts.
You create them in PROJECT_HOME/db/mysql/testdb
db/mysql/testdb/build-mysql-testdb.xml
db/mysql/testdb/createTables.sql
db/mysql/testdb/dropTables.sql
db/mysql/testdb/populateTables.sql
db/mysql/testdb/testData.sql
The build script itself is fairly self-explanatory.  It replicates the targets from the master build script.  It reads the mysql.properties and schema.properties files and adds the correct jar file to the classpath.
For [...]]]></description>
			<content:encoded><![CDATA[<p>Having set up the basic folder structure in <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQuY29tLzIwMDkvMDMvMjUvYXV0b21hdGVkLWJ1aWxkLWRhdGFiYXNlLXNjcmlwdHMvP3V0bV9jYW1wYWlnbj1mZWVkJnV0bV9tZWRpdW09ZmVlZCZ1dG1fc291cmNlPWJsb2c=">Automated Build Databse scripts</a> you now need to add the mysql scripts.</p>
<p>You create them in PROJECT_HOME/db/mysql/testdb
<code>db/mysql/testdb/build-mysql-testdb.xml
db/mysql/testdb/createTables.sql
db/mysql/testdb/dropTables.sql
db/mysql/testdb/populateTables.sql
db/mysql/testdb/testData.sql</code></p>
<p>The build script itself is fairly self-explanatory.  It replicates the targets from the master build script.  It reads the mysql.properties and schema.properties files and adds the correct jar file to the classpath.</p>
<p>For each target you first check if the property mysql.db.enable has been set so the target will only run if you’ve configured schema.properties to include the mysql database.   For each target you connect to the database and execute the sql in the appropriate sql script.</p>
<p>mysql/testdb/build-mysql-testdb.xml:
<code>&lt;?xml version="1.0"?&gt;

&lt;project basedir="."  name="-build"&gt;

  &lt;property file="../../config/mysql.properties" /&gt;
  &lt;property file="../../config/schema.properties" /&gt;
  &lt;property name="lib.dir" value="../../lib" /&gt;

  &lt;!-- Class path settings --&gt;
  &lt;fileset id="lib" dir="${lib.dir}/mysql"&gt;
    &lt;include name="*.jar" /&gt;
  &lt;/fileset&gt;
  &lt;path id="classpath"&gt;
    &lt;fileset refid="lib" /&gt;
  &lt;/path&gt;

  &lt;target name="createUser" if="mysql.db.enable" description="Creates user and schema specified in properties file"&gt;
    &lt;echo&gt;Executing mysql-airline:createUser &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      url="${mysql.url}"
      userid="${mysql.rootuser}"
      password="${mysql.rootpass}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;

        create schema ${mysql.schema};
        GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,INDEX,DROP
        ON ${mysql.schema}.*
        TO '${mysql.username}'@'${mysql.user.location}'
        IDENTIFIED BY '${mysql.password}';
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="dropUser" if="mysql.db.enable" description="Drops user and schema specified in properties file"&gt;
    &lt;echo&gt;Executing mysql-airline:dropUser &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      url="${mysql.url}"
      userid="${mysql.rootuser}"
      password="${mysql.rootpass}"
      print="${print}"
      onerror="continue"&gt;
      &lt;classpath refid="classpath"/&gt;

      drop schema ${mysql.schema};
      drop user '${mysql.username}'@'${mysql.user.location}';
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="recreateTables" if="mysql.db.enable" depends="dropUser,createUser,createTables,populateTables,testData" description="refreshes the database tables"/&gt;

  &lt;target name="createTables" if="mysql.db.enable" description="Creates Database Tables"&gt;
    &lt;echo&gt;Executing mysql-airline:createTables &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      src="${mysql.create.tables.script}"
      url="${mysql.url}/${mysql.schema}"
      userid="${mysql.username}"
      password="${mysql.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="populateTables" if="mysql.db.enable" description="Populates Database Tables"&gt;
    &lt;echo&gt;Executing mysql-airline:populateTables &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      src="${mysql.populate.tables.script}"
      url="${mysql.url}/${mysql.schema}"
      userid="${mysql.username}"
      password="${mysql.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="dropTables" if="mysql.db.enable" description="Drops Database Tables"&gt;
    &lt;echo&gt;Executing mysql-airline:dropTables &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      url="${mysql.url}/${mysql.schema}"
      userid="${mysql.username}"
      password="${mysql.password}"
      src="${mysql.drop.tables.script}"
      print="${print}"
      onerror="continue"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="testData" if="mysql.db.enable" description="Refreshes test data"&gt;
    &lt;echo&gt;Executing mysql-airline:testData &lt;/echo&gt;
    &lt;sql driver="${mysql.driver}"
      src="${mysql.testdata.script}"
      url="${mysql.url}/${mysql.schema}"
      userid="${mysql.username}"
      password="${mysql.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

&lt;/project&gt;</code></p>
<p>You then edit the sql scripts to add the tables and data needed for your schema.  Note that for targets that drop tables or users we set onerror=&#8221;continue&#8221; so that the build won&#8217;t fail if you add in new tables and attempt to drop them before they&#8217;ve been created.</p>
<br /><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQud29yZHByZXNzLmNvbS8/cD0yMDIjY29tbWVudHM=" title=\"Comments on &quot;Automated Build &#8211; Mysql database scripts&quot;\"><img src="http://sheilapollard.com/wp-content/plugins/feed-comments-number/image.php?202" alt="Comments" /></a> <img src="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?view=1&post_id=202" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://sheilapollard.com/2009/03/30/automated-build-mysql-database-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automated Build &#8211; OracleXe database scripts</title>
		<link>http://sheilapollard.com/2009/03/27/automated-build-oraclexe-database-scripts/?utm_campaign=feed&utm_medium=feed&utm_source=blog</link>
		<comments>http://sheilapollard.com/2009/03/27/automated-build-oraclexe-database-scripts/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 12:08:37 +0000</pubDate>
		<dc:creator>Sheila</dc:creator>
				<category><![CDATA[build]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[automated build]]></category>
		<category><![CDATA[oraclexe]]></category>

		<guid isPermaLink="false">http://sheilapollard.wordpress.com/?p=200</guid>
		<description><![CDATA[Having set up the database folder structure in Automated Build Database scripts you now need to add the oracle xe scripts.
You create them in PROJECT_HOME/db/oraclexe/testdb
db/oraclexe/testdb/build-oraclexe-testdb.xml
db/oraclexe/testdb/createTables.sql
db/oraclexe/testdb/dropTables.sql
db/oraclexe/testdb/populateTables.sql
db/oraclexe/testdb/testData.sql
The build script itself is fairly self-explanatory.  It replicates the targets from the master build script.  It reads the xe.properties and schema.properties files and adds the correct jar file to the [...]]]></description>
			<content:encoded><![CDATA[<p>Having set up the database folder structure in <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQuY29tLzIwMDkvMDMvMjUvYXV0b21hdGVkLWJ1aWxkLWRhdGFiYXNlLXNjcmlwdHMvP3V0bV9jYW1wYWlnbj1mZWVkJnV0bV9tZWRpdW09ZmVlZCZ1dG1fc291cmNlPWJsb2c=">Automated Build Database scripts</a> you now need to add the oracle xe scripts.</p>
<p>You create them in PROJECT_HOME/db/oraclexe/testdb
<code>db/oraclexe/testdb/build-oraclexe-testdb.xml
db/oraclexe/testdb/createTables.sql
db/oraclexe/testdb/dropTables.sql
db/oraclexe/testdb/populateTables.sql
db/oraclexe/testdb/testData.sql</code></p>
<p>The build script itself is fairly self-explanatory.  It replicates the targets from the master build script.  It reads the xe.properties and schema.properties files and adds the correct jar file to the classpath.</p>
<p>For each target you first check if the property oraclexe.db.enable has been set so the target will only run if you&#8217;ve configured schema.properties to include the oraclexe database.   Then in each target you connect to the database and execute the statements in the appropriate sql script.</p>
<p>oraclexe/testdb/build-xe-testdb.xml:
<code>&lt;?xml version="1.0"?&gt;

&lt;project basedir="." name="xe-mdm-build"&gt;

  &lt;property file="../../config/schema.properties" /&gt;
  &lt;property file="../../config/xe.properties" /&gt;
  &lt;property name="template.dir" value="../templates" /&gt;
  &lt;property name="lib.dir" value="../../lib" /&gt;
  &lt;property name="build.dir" value="../../build" /&gt;

  &lt;!-- Class path settings --&gt;
  &lt;fileset id="lib" dir="${lib.dir}/oracle"&gt;
    &lt;include name="*.jar" /&gt;
  &lt;/fileset&gt;
  &lt;path id="classpath"&gt;
    &lt;fileset refid="lib" /&gt;
  &lt;/path&gt;

  &lt;target name="init" if="xe.db.enable"&gt;
    &lt;mkdir dir="${build.dir}"/&gt;
  &lt;/target&gt;

  &lt;target name="clean" if="xe.db.enable"&gt;
    &lt;delete dir="${build.dir}"/&gt;
  &lt;/target&gt;

  &lt;target name="gen-sql" if="xe.db.enable" depends="clean,init" description="Generates the sql files"&gt;
    &lt;copy file="${template.dir}/createUser.template" tofile="${build.dir}/createTestUser.sql" overwrite="true"&gt;
      &lt;!-- replace template tokens marked with ~~ before and after --&gt;
      &lt;filterset begintoken="~~" endtoken="~~"&gt;
        &lt;filter token="template.username" value="${xe.username}" /&gt;
        &lt;filter token="template.password" value="${xe.password}" /&gt;
      &lt;/filterset&gt;
    &lt;/copy&gt;
    &lt;copy file="${template.dir}/dropUser.template" tofile="${build.dir}/dropTestUser.sql" overwrite="true"&gt;
      &lt;!-- replace template tokens marked with ~~ before and after --&gt;
      &lt;filterset begintoken="~~" endtoken="~~"&gt;
        &lt;filter token="template.username" value="${xe.username}" /&gt;
      &lt;/filterset&gt;
    &lt;/copy&gt;
  &lt;/target&gt;

  &lt;target name="createUser" if="xe.db.enable" depends="gen-sql" description="Creates user specified in properties file"&gt;
    &lt;echo&gt;Executing xe-mdm:createUser &lt;/echo&gt;
    &lt;exec dir="${template.dir}" executable="cmd"&gt;
      &lt;arg line="/c run.bat ${xe.rootuser} ${xe.rootpass} ${xe.sid} ${build.dir}/createTestUser.sql"/&gt;
    &lt;/exec&gt;
  &lt;/target&gt;

  &lt;target name="dropUser" if="xe.db.enable" depends="gen-sql" description="Creates user specified in properties file"&gt;
    &lt;echo&gt;Executing xe-mdm:dropUser &lt;/echo&gt;
    &lt;exec dir="${template.dir}" executable="cmd"&gt;
      &lt;arg line="/c run.bat ${xe.rootuser} ${xe.rootpass} ${xe.sid} ${build.dir}/dropTestUser.sql"/&gt;
    &lt;/exec&gt;
  &lt;/target&gt;

  &lt;target name="recreateTables" depends="dropTables,createTables,populateTables,testData" description="Refreshes the database tables"/&gt;

  &lt;target name="createTables" if="xe.db.enable" description="Creates Database Tables"&gt;
    &lt;echo&gt;Executing xe-mdm:createtables &lt;/echo&gt;
    &lt;sql driver="${xe.driver}"
      src="${xe.create.tables.script}"
      url="${xe.url}"
      userid="${xe.username}"
      password="${xe.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="populateTables" if="xe.db.enable" description="Populates Database Tables"&gt;
    &lt;echo&gt;Executing xe-mdm:populateTables &lt;/echo&gt;
    &lt;sql driver="${xe.driver}"
      src="${xe.populate.tables.script}"
      url="${xe.url}"
      userid="${xe.username}"
      password="${xe.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="dropTables" if="xe.db.enable" description="Drops the Database Tables"&gt;
    &lt;echo&gt;Executing xe-mdm:dropTables &lt;/echo&gt;
    &lt;sql driver="${xe.driver}"
      src="${xe.drop.tables.script}"
      url="${xe.url}"
      userid="${xe.username}"
      password="${xe.password}"
      print="${print}"
      onerror="continue"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

  &lt;target name="testData" if="xe.db.enable" description="Refreshes test data"&gt;
    &lt;echo&gt;Executing xe-mdm:testData &lt;/echo&gt;
    &lt;sql driver="${xe.driver}"
      src="${xe.testdata.script}"
      url="${xe.url}"
      userid="${xe.username}"
      password="${xe.password}"
      print="${print}"&gt;
      &lt;classpath refid="classpath"/&gt;
    &lt;/sql&gt;
  &lt;/target&gt;

&lt;/project&gt;</code></p>
<p>For oraclexe you need to generate scripts for creating and dropping the user and run them from a batch file.  The values in xe.properties are used to fill in the details.  Create the following templates:</p>
<p>oraclexe/templates/createUser.template:
<code>create user ~~template.username~~ identified by ~~template.password~~
DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA 50M ON users;
GRANT CONNECT, RESOURCE TO ~~template.username~~;</code></p>
<p>oraclexe/templates/dropUser.template:
<code&gt;drop USER ~~template.username~~ CASCADE;&lt;/code></p>
<p>In createUser.template we want to sustitute a value for the token template.username.  We choose ~~ to indicate the start and end of the token.  In the gen-sql target you state the start and end of the tokens are ~~ and indicate which value should replace the token in the template.  In this case ~~template.username~~ will be replaced with the xe.username value.  The generated sql scripts will be stored in db/build.</p>
<p>oraclexe/templates/run.bat:<code>@echo off

SET sysdba_userid=%1
SET sysdba_psswd=%2
SET sid=%3
SET sql_file=%4

SQLPlus %sysdba_userid%/%sysdba_psswd%@%sid% as sysdba @%sql_file%

echo Finished processing, exiting ...</code></p>
<p>The createUser and dropUser targets are run after gen-sql.  They execute a command line prompt and pass the database connection details and sql script to run.bat before launching it.</p>
<p>Now the only thing left to do is add the sql statements to the .sql scripts to create the database you want.  Note that for targets that drop tables or users we set onerror="continue" so that the build won't fail if you add in new tables and attempt to drop them before they've been created.</p>
<br /><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQud29yZHByZXNzLmNvbS8/cD0yMDAjY29tbWVudHM=" title=\"Comments on &quot;Automated Build &#8211; OracleXe database scripts&quot;\"><img src="http://sheilapollard.com/wp-content/plugins/feed-comments-number/image.php?200" alt="Comments" /></a> <img src="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?view=1&post_id=200" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://sheilapollard.com/2009/03/27/automated-build-oraclexe-database-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automated Build &#8211; Database scripts</title>
		<link>http://sheilapollard.com/2009/03/25/automated-build-database-scripts/?utm_campaign=feed&utm_medium=feed&utm_source=blog</link>
		<comments>http://sheilapollard.com/2009/03/25/automated-build-database-scripts/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 17:42:38 +0000</pubDate>
		<dc:creator>Sheila</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[automated build]]></category>
		<category><![CDATA[database scripts]]></category>

		<guid isPermaLink="false">http://sheilapollard.wordpress.com/?p=197</guid>
		<description><![CDATA[When you&#8217;re developing a project, you put all your java code into source control.  You should also include database scripts in source control.  These scripts can be used by developers to keep their local copies of the database up to date in the same way as they get the latest code from source control.
As part [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re developing a project, you put all your java code into source control.  You should also include database scripts in source control.  These scripts can be used by developers to keep their local copies of the database up to date in the same way as they get the latest code from source control.</p>
<p>As part of your automated build system you should run the database scripts whenever there&#8217;s a change to keep your code and database in synch.  You can add the code into your existing build in a db folder or check it into source control separately.</p>
<p>You follow almost the same process whether adding scripts for mysql or oraclexe and can modify the scripts to cater for multiple schemas across different databases.   In this example we&#8217;ll cover the configuration for setting up the testdb schema in both oraclexe and mysql before writing the scripts for each.  This example assumes you already have both databases running locally on your machine.</p>
<p>To start with you create a PROJECT_HOME/db folder which contains:
<code>db/config
db/datasources
db/lib
db/oraclexe/testdb
db/mysql/testdb</code></p>
<p>In the lib folder add the connector jars for the databases eg.
<code>db/lib/oracle/ojdbc5.jar
db/lib/mysql/mysql-connector-java-5.1.6-bin.jar</code></p>
<p>In the config folder we need some property files to configure the build.
<code>db/config/mysql.properties
db/config/xe.properties
db/config/schema.properties</code></p>
<p>Schema.properties is used to configure the build depending on whether you want to just use oracle xe or mysql or use both.  In this example oraclexe is enabled and mysql is disabled.</p>
<p>schema.properties:
<code>##
## Use this property file to enable or disable the databases and
## schemas you want to run the build scripts against.
## Comment them out with a # if you don't want to enable a
## setting.

#Databases

xe.db.enable
xe.username=testdb
xe.password=testdb

#mysql.db.enable
#mysql.username=testdb
#mysql.password=testdb</code></p>
<p>The next two give the access details for your oracle xe and mysql databases.</p>
<p>mysql.properties:
<code># MySql Database Details
mysql.rootuser=root
mysql.rootpass=password
mysql.url=jdbc:mysql://localhost:3306
mysql.schema=testdb

mysql.driver=com.mysql.jdbc.Driver
mysql.user.location=localhost

mysql.create.tables.script=createTables.sql
mysql.drop.tables.script=dropTables.sql
mysql.populate.tables.script=populateTables.sql
mysql.testdata.script=testData.sql

print=false</code></p>
<p>xe.properties:
<code># Oracle XE Database Details
xe.rootuser=sys
xe.host=localhost
xe.sid=XE
xe.rootpass=password

xe.port=1521
xe.driver=oracle.jdbc.OracleDriver
xe.url=jdbc:oracle:thin:@${xe.host}:${xe.port}:${xe.sid}

xe.create.user.script=createUser.sql
xe.delete.user.script=dropUser.sql
xe.create.tables.script=createTables.sql
xe.drop.tables.script=dropTables.sql
xe.populate.tables.script=populateTables.sql
xe.testdata.script=testdata.sql

print=false</code></p>
<p>We start off with a master build.xml script in PROJECT_HOME which calls oraclexe/testdb/build-xe-testdb.xml and mysql/testdb/build-mysql-testdb.xml script.  The &#8216;ant dir&#8217; value specifies the directory the script to be called in, &#8216;antfile&#8217; gives the name of the script, and lastly you specify the target to be run in that script.</p>
<p>db/build.xml:
<code>&lt;?xml version="1.0"?&gt;

&lt;project basedir="." name="db-master-build" default="recreateTables"&gt;

  &lt;property name="build.dir" value="${basedir}/build" /&gt;

  &lt;target name="clean"&gt;
    &lt;delete dir="${build.dir}" failonerror="false" /&gt;
  &lt;/target&gt;

  &lt;target name="install" depends="createUsers,createTables,populateTables,testData" description="Creates all users and schemas for a fresh install" /&gt;

  &lt;target name="recreateTables" description="Refreshes the database tables for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="recreateTables" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="recreateTables" /&gt;
  &lt;/target&gt;

  &lt;target name="createUsers" description="Creates users for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="createUser" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="createUser" /&gt;
  &lt;/target&gt;

  &lt;target name="dropUsers" description="Drops users for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="dropUser" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="dropUser" /&gt;
  &lt;/target&gt;

  &lt;target name="createTables" description="Creates Database Tables for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="createTables" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="createTables" /&gt;
  &lt;/target&gt;

  &lt;target name="populateTables" description="Populates Database Tables for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="populateTables" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="populateTables" /&gt;
  &lt;/target&gt;

  &lt;target name="dropTables" description="Drops Database Tables for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="dropTables" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="dropTables" /&gt;
  &lt;/target&gt;

  &lt;target name="testData" description="Refreshes test data for all schemas"&gt;
    &lt;ant dir="oraclexe/testdb" antfile="build-xe-testdb.xml" target="testData" /&gt;
    &lt;ant dir="mysql/testdb" antfile="build-mysql-testdb.xml" target="testData" /&gt;
  &lt;/target&gt;

&lt;/project&gt;</code></p>
<p>The install target is used to create the database schemas from scratch &#8211; including the users.</p>
<p>The recreateTables target is the default and is used when the schemas and users already exist and you just want to drop and create the tables to pick up changes.</p>
<p>The rest of the targets can be called separately for creating tables, populating them with default data (eg. lists of countries that would always be needed for an application) adding some test data and deleting the tables again.</p>
<p>The next step is to add the <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQuY29tLzIwMDkvMDMvMjcvYXV0b21hdGVkLWJ1aWxkLW9yYWNsZXhlLWRhdGFiYXNlLXNjcmlwdHMvP3V0bV9jYW1wYWlnbj1mZWVkJnV0bV9tZWRpdW09ZmVlZCZ1dG1fc291cmNlPWJsb2c=">oraclexe</a>-specific scripts and the <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQuY29tLzIwMDkvMDMvMzAvYXV0b21hdGVkLWJ1aWxkLW15c3FsLWRhdGFiYXNlLXNjcmlwdHMv">mysql</a>-specific scripts.</p>
<br /><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQud29yZHByZXNzLmNvbS8/cD0xOTcjY29tbWVudHM=" title=\"Comments on &quot;Automated Build &#8211; Database scripts&quot;\"><img src="http://sheilapollard.com/wp-content/plugins/feed-comments-number/image.php?197" alt="Comments" /></a> <img src="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?view=1&post_id=197" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://sheilapollard.com/2009/03/25/automated-build-database-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating your Build &#8211; The Very Basics for a Beginner</title>
		<link>http://sheilapollard.com/2009/03/24/automating-your-build-the-very-basics-for-a-beginner/?utm_campaign=feed&utm_medium=feed&utm_source=blog</link>
		<comments>http://sheilapollard.com/2009/03/24/automating-your-build-the-very-basics-for-a-beginner/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 12:58:40 +0000</pubDate>
		<dc:creator>Sheila</dc:creator>
				<category><![CDATA[build]]></category>
		<category><![CDATA[ant]]></category>

		<guid isPermaLink="false">http://sheilapollard.wordpress.com/?p=178</guid>
		<description><![CDATA[This post covers the absolute basics for a beginner of setting up a minimal build script for building and deploying code as a jar/war/ear file.]]></description>
			<content:encoded><![CDATA[<p>This post covers the absolute basics for a beginner of setting up a minimal build script for building and deploying code as a jar/war/ear file.  The aim is to show a simple build structure and script rather than building a proper application.  The scripts are mostly self-explanatory.  The end result can be used as a starting point for later posts covering more difficult topics including building sample applications, testing and automating your build with <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2NydWlzZWNvbnRyb2wuc291cmNlZm9yZ2UubmV0">CruiseControl</a>.</p>
<p><em>Prerequisite:</em><br />
You need java and <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2FudC5hcGFjaGUub3JnLw==">ant</a> installed on your machine and running from a command prompt.</p>
<p>The first thing you need when setting up a new project is to decide on the structure.  By using standard conventions about how you structure your code it makes it easier for others to work on it.  You&#8217;ll see a similar type of build structure used in tools like Seam&#8217;s seamgen except more complicated than this one.</p>
<p>The root folder of your project will be referred to as PROJECT_HOME in these notes.  The first thing to do is create the following folders in PROJECT_HOME:<br />
config &#8211; holds configuration files<br />
lib &#8211; holds any jar files<br />
resources &#8211; resource and config files to be copied into a jar, war or ear file during the build<br />
src &#8211; for source java files<br />
web &#8211; for web applications pages, css, images etc</p>
<p>Now add an ant build script file PROJECT_HOME/build.xml which is used to build the project.  Also add PROJECT_HOME/config/build.properties.sample.  This file is added to source control.  Each user that checks out the project will copy this file and rename it to build.properties which will be used by the build script.  Any subsequent changes to the property file in source control will not overwrite a local user&#8217;s settings and this also forces a user to set the properties correctly when checking out a new project.</p>
<p>PROJECT_HOME/config/build.properties.sample:
<code>project.name=example
web.pages.dir=web

javac.debug=true
javac.deprecation=false

jboss.home = C:/Applications/jboss-4.2.2.GA/</code></p>
<p>We start with a basic build script that reads the build.properties file, adds some other properties, a class path and the targets init, compile and clean.  We&#8217;ll add to this as we go along.</p>
<p>The build process generates the folder structure for a jar file, war file and ear file in exploded-archives.  It will then package those into actual archive files in the dist directory.  This allows you to check what&#8217;s being added without having to examine the final archive files.  You also configure a directory to deploy in this case an ear file to a web application server.</p>
<p>PROJECT_HOME/build.xml
<code>&lt;project name="example" default="compile" basedir="."&gt;

  &lt;!-- set properties for this build --&gt;
  &lt;property name="config.dir" value="config" /&gt;
  &lt;property file="${config.dir}/build.properties" /&gt;

  &lt;property name="src.dir" value="src" /&gt;
  &lt;property name="lib.dir" value="lib" /&gt;
  &lt;property name="resources.dir" value="resources" /&gt;
  &lt;property name="dist.dir" value="dist" /&gt;
  &lt;property name="archive.dir" value="exploded-archives" /&gt;
  &lt;property name="ear.dir" value="${archive.dir}/${project.name}.ear" /&gt;
  &lt;property name="jar.dir" value="${archive.dir}/${project.name}.jar" /&gt;
  &lt;property name="war.dir" value="${archive.dir}/${project.name}.war" /&gt;
  &lt;property name="deploy.dir" value="${jboss.home}/server/default/deploy" /&gt;

  &lt;!-- Class path settings --&gt;
  &lt;fileset id="lib" dir="${lib.dir}"&gt;
    &lt;include name="*.jar" /&gt;
  &lt;/fileset&gt;
  &lt;path id="build.classpath"&gt;
    &lt;fileset refid="lib" /&gt;
  &lt;/path&gt;

  &lt;target name="init" description="Initialize the build"&gt;
    &lt;echo&gt;Initialising build...&lt;/echo&gt;
    &lt;mkdir dir="${jar.dir}" /&gt;
    &lt;mkdir dir="${ear.dir}" /&gt;
    &lt;mkdir dir="${war.dir}" /&gt;
    &lt;mkdir dir="${archive.dir}" /&gt;
    &lt;mkdir dir="${dist.dir}" /&gt;
  &lt;/target&gt;

  &lt;target name="compile" depends="init" description="Compile the Java source code"&gt;
    &lt;echo&gt;Compiling java source code...&lt;/echo&gt;
    &lt;javac classpathref="build.classpath" destdir="${jar.dir}" debug="${javac.debug}" deprecation="${javac.deprecation}" nowarn="on"&gt;
      &lt;src path="${src.dir}" /&gt;
    &lt;/javac&gt;
  &lt;/target&gt;

  &lt;target name="clean" description="Cleans up the build directorys"&gt;
    &lt;echo&gt;Cleaning build directories...&lt;/echo&gt;
    &lt;delete dir="${ear.dir}" /&gt;
    &lt;delete dir="${war.dir}" /&gt;
    &lt;delete dir="${jar.dir}" /&gt;
    &lt;delete dir="${archive.dir}" /&gt;
    &lt;delete dir="${dist.dir}" /&gt;
  &lt;/target&gt;

&lt;/project&gt;</code></p>
<p>The build.classpath is set to simply include any jar files in the lib folder.</p>
<p>The init target creates any directories that are needed by the build.</p>
<p>The clean target deletes any directories that were created by the build.</p>
<p>The compile target looks in the src folder for any .java files and compiles them into the exploded-archives/example.jar folder.</p>
<p>To test the build script add the file</p>
<p>PROJECT_HOME/src/com/example/Parent.java
<code>package com.example;

public class Parent {

  private Long parentId;

  public Long getParentId() {
    return this.parentId;
  }

  public void setParentId(Long parentId) {
    this.parentId = parentId;
  }
}</code></p>
<p>Open a command prompt in the PROJECT_HOME folder and run the command &#8216;ant&#8217;.  By default (default=&#8221;compile&#8221;) it will run the compile target.  The compile target states that it depends on the init target, so the init target will be run first to create the folders that are needed.  When the script finishes running you will find that exploded-archives/example.jar/com/example contains the compiled Parent.class.</p>
<p>We want to build and deploy a web application so we add the target gen-war-files which will be used to copy anything that&#8217;s needed into the exploded war file before it gets packaged.  We&#8217;ll start with a target like this:
<code>&lt;?xml version="1.0"?&gt;

  &lt;target name="gen-war-files" depends="compile" description="Generates the war files"&gt;
    &lt;echo&gt;Copying war files...&lt;/echo&gt;
    &lt;copy todir="${war.dir}"&gt;
      &lt;fileset dir="${basedir}/${web.pages.dir}/pages" /&gt;
    &lt;/copy&gt;
    &lt;copy todir="${war.dir}"&gt;
      &lt;fileset dir="${basedir}/${web.pages.dir}"&gt;
        &lt;include name="images/**/*" /&gt;
        &lt;include name="css/**/*" /&gt;
      &lt;/fileset&gt;
    &lt;/copy&gt;
    &lt;copy todir="${war.dir}/WEB-INF/lib"&gt;
      &lt;fileset dir="${lib.dir}"&gt;
        &lt;includesfile name="${config.dir}/war-jars.list" /&gt;
      &lt;/fileset&gt;
    &lt;/copy&gt;
    &lt;copy todir="${war.dir}/WEB-INF"&gt;
      &lt;fileset dir="${resources.dir}/WEB-INF"&gt;
        &lt;include name="*.*"/&gt;
      &lt;/fileset&gt;
    &lt;/copy&gt;
  &lt;/target&gt;</code></p>
<p>A war file contains a WEB-INF folder where compiled classes and required jar files are put.  Also files such as web.xml which gives configuration and deployment for the web components.  So create resources/WEB-INF.</p>
<p>PROJECT_HOME/resources/WEB-INF/web.xml
<code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;

&lt;/web-app&gt;</code></p>
<p>The build script copies any files in resources/WEB-INF to the war folder and also copies any jar files that are needed to the WEB-INF/lib folder.  You can configure which of the jar files in PROJECT_HOME/lib get copied over in PROJECT_HOME/config/war-jars.list.  For now just create an empty file of that name in the config folder.</p>
<p>This target copies any files in web/pages to exploded-archives/example.war and will also copy over the images and css folders.  We don&#8217;t have any files to copy at the moment, but will add an index page to see that it does get added.</p>
<p>web/pages/index.jsp
<code>&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;The Index Page&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    Index page
  &lt;/body&gt;
&lt;/html&gt;</code></p>
<p>Try the command &#8216;ant gen-war-files&#8217; and you will see that exploded-archives/example.war now contains the index page.</p>
<p>We now add the gen-ear-files and archive targets.  Similarly to the war file, the ear file requires a META-INF folder containing information about the ear file.  So you can add resources/META-INF for holding these files and an empty config/ear-jars.list to configure which jar files are needed in the ear file.  We  will add an application.xml which is the deployment descriptor for ear files.</p>
<p>resources/META-INF/application.xml
<code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;application xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/application_5.xsd" 
    version="5"&gt;

    &lt;display-name&gt;example&lt;/display-name&gt;
    &lt;module&gt;
      &lt;ejb&gt;example.jar&lt;/ejb&gt;
    &lt;/module&gt;
    &lt;module&gt;
      &lt;web&gt;
        &lt;web-uri&gt;example.war&lt;/web-uri&gt;
        &lt;context-root&gt;/example&lt;/context-root&gt;
      &lt;/web&gt;
    &lt;/module&gt;
  &lt;/application&gt;</code></p>
<p>The gen-ear-files target will take care of copying this to the correct location in the ear file then the archive target will take all the output in exploded-archives and package up all the files into the dist directory.  Test this using &#8216;ant archive&#8217;
<code>&lt;target name="gen-ear-files" depends="gen-war-files" description="Generates the ear files"&gt;
  &lt;echo&gt;Copying the ear files...&lt;/echo&gt;
  &lt;mkdir dir="${ear.dir}/lib" /&gt;
  &lt;copy todir="${ear.dir}/lib"&gt;
    &lt;fileset dir="${lib.dir}"&gt;
      &lt;includesfile name="${config.dir}/ear-jars.list" /&gt;
    &lt;/fileset&gt;
  &lt;/copy&gt;

  &lt;copy todir="${ear.dir}/META-INF"&gt;
    &lt;fileset dir="${resources.dir}/META-INF"&gt;
      &lt;include name="*.*"/&gt;
    &lt;/fileset&gt;
  &lt;/copy&gt;
&lt;/target&gt;

&lt;target name="archive" depends="gen-war-files,gen-ear-files" description="Packages all the archives"&gt;
  &lt;echo&gt;Packaging all archives...&lt;/echo&gt;
  &lt;jar jarfile="${dist.dir}/${project.name}.jar" basedir="${jar.dir}" /&gt;
  &lt;jar jarfile="${dist.dir}/${project.name}.war" basedir="${war.dir}" /&gt;
  &lt;jar jarfile="${dist.dir}/${project.name}.ear"&gt;
    &lt;fileset dir="${ear.dir}"/&gt;
    &lt;fileset dir="${dist.dir}"&gt;
      &lt;include name="${project.name}.jar"/&gt;
      &lt;include name="${project.name}.war"/&gt;
    &lt;/fileset&gt;
  &lt;/jar&gt;
&lt;/target&gt;</code></p>
<p>We now want to deploy the ear file that has been created to a web application server.  In our example we&#8217;re using JBoss.  You set the jboss.home directory in build.properties already.  Now add some more build targets
<code>&lt;target name="clean-deploy" depends="clean, deploy" description="A full clean deploy"/&gt;

&lt;target name="deploy" depends="archive" description="Deploy to a JBoss web server"&gt;
  &lt;echo&gt;Deploying to JBOSS web server...&lt;/echo&gt;
  &lt;fail unless="jboss.home"&gt;jboss.home not set&lt;/fail&gt;
  &lt;copy todir="${deploy.dir}" file="${dist.dir}/${project.name}.ear" /&gt;
&lt;/target&gt;

&lt;target name="undeploy" description="Undeploy from a JBoss web server"&gt;
  &lt;echo&gt;Undeploying from JBOSS web server...&lt;/echo&gt;
  &lt;delete file="${deploy.dir}/${project.name}.ear" /&gt;
&lt;/target&gt;</code></p>
<p>Now run the clean-deploy target (set this to default) and try accessing http://localhost:8080/example/<br />
You should see the index page display if everything is working correctly.  You now have an extremely basic build script running.  You should go through each line and check that you understand what it does &#8211; you can get more detailed information in the <a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL2FudC5hcGFjaGUub3JnL21hbnVhbC9pbmRleC5odG1s">Ant User Manual</a>.</p>
<br /><a href="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?url=aHR0cDovL3NoZWlsYXBvbGxhcmQud29yZHByZXNzLmNvbS8/cD0xNzgjY29tbWVudHM=" title=\"Comments on &quot;Automating your Build &#8211; The Very Basics for a Beginner&quot;\"><img src="http://sheilapollard.com/wp-content/plugins/feed-comments-number/image.php?178" alt="Comments" /></a> <img src="http://sheilapollard.com/wp-content/plugins/feed-statistics.php?view=1&post_id=178" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://sheilapollard.com/2009/03/24/automating-your-build-the-very-basics-for-a-beginner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
