Java/Hibernate ant build example

This is the contents of a typical ant build file I use for Java coding projects. It’s up here in case it can help anyone else, and so I can copy and paste it when working off-site.

The process is fairly simple, I have my working area in a ~/projects/myapp folder (where myapp is name of current project). I have lib files in ~/projects/java/lib/

I run the build in the myapp file, the ant file reads the build.properties file for some config info and dumps the build outputs to the $targetdir folder (~/projects/bin)

Firstly, the build.properties file

# options: linux, windows, mac                                                  
gwt.os = linux

#Directories                                                                    
gwt.installation.dir = ~/google/gwt-windows-1.5.3
#note env is defined in build.xml file                                          
gwt.dir=${env.GWT_HOME}
tomcat.dir=${env.TOMCAT_HOME}
hibernate.dir=${env.HIBERNATE_HOME}
postgresql.dir=${env.POSTGRES_HOME}
asm.dir=${env.ASM_HOME}
spring.dir=${env.SPRING_HOME}
loglib.dir=${env.LOGLIB_HOME}
junit.dir=${env.JUNIT_HOME}

#JAR files                                                                      
servlet.api.jar=${tomcat.dir}/lib/servlet-api.jar
gwt.servlet.jar=${gwt.dir}/gwt-servlet.jar
hibernate3.jar=${hibernate.dir}/hibernate3.jar
postgresql.driver.jar=${postgresql.dir}/postgresql-8.3-604.jdbc4.jar
asm.jar=${asm.dir}/asm-3.1.jar
loglib.jar=${loglib.dir}/commons-logging-1.1.1.jar
junit.jar=${junit.dir}/junit-4.5.jar
#google web toolkit jars
gwt.user.jar = ${gwt.installation.dir}/gwt-user.jar
gwt.servlet.jar = ${gwt.installation.dir}/gwt-servlet.jar
gwt.dev.jar = ${gwt.installation.dir}/gwt-dev-${gwt.os}.jar
build.dir = ../build
classes.dir = ${build.dir}/classes
jar.dir = ${build.dir}/jar
gwt.output = ${build.dir}/www

sourcedir = ${basedir}/src
targetdir = ${basedir}/bin
includedir = c:/projects/java/lib
testdir = ${basedir}/test
resdir = ${basedir}/res
reportsdir = ${basedir}/reports
appdir = ${basedir}
wwwdir = ${appdir}/www/com.petermac.${app}
spring.conf.dir = ${basedir}/src/META-INF/spring
hibernate.conf.dir = ${basedir}/src/META-INF/hibernate

Now for the actual ant file. This is specific to a GWT application, but you can easily knock out the google bits and use the rest without any changes.

<?xml version="1.0" encoding="utf-8" ?>
<project name="ClaimsManager" default="compile" basedir=".">
    <property name="TALK" value="false" />
    <!-- Define the environment property variable -->
    <property environment="env" />
    <!-- Define where our properties are located -->
    <property file="build.properties" />
    <description>
        ClaimsManager build file.  This is used to package up your project as a jar,
        if you want to distribute it.  This isn't needed for normal operation.
    </description> 

    <!-- set classpath -->
    <path id="classpath">
        <pathelement location="${sourcedir}"/>
        <pathelement location="${servlet.api.jar}" />
        <pathelement location="${gwt.servlet.jar}" />
        <pathelement location="${asm.jar}" />
        <pathelement location="${postgresql.driver.jar}" />
        <pathelement location="${loglib.jar}" />

        <fileset dir="${includedir}">
            <include name="*.jar" />
        </fileset>

        <fileset dir="${spring.dir}">
            <include name="*.jar" />
        </fileset>
    </path>
    <path id="gwt.compile.class.path">
          <pathelement location="${sourcedir}"/>
          <pathelement location="${testdir}"/>
          <pathelement path="${gwt.user.jar}"/>
          <pathelement path="${gwt.dev.jar}"/>
          <pathelement path="${wwwdir}/WEB-INF/classes/com/petermac/claimsmanager/server/service"/>
       </path>
       <path id="test.classpath">
          <pathelement location="${junit.jar}" />
      <pathelement location="${gwt.user.jar}"/>
      <pathelement path="${targetdir}"/>
      <fileset dir="${includedir}">
          <include name="*.jar" />
      </fileset>
      <fileset dir="${spring.dir}">
          <include name="*.jar" />
      </fileset>
    </path>
   
    <target name="init" description="Initialize the build environment">
        <fail unless="app" message="Run ant -Dapp=[applicationName]"/>
        <!-- Create the time stamp -->
        <tstamp/>

        <echo message="Building on ${TODAY} at ${TSTAMP}" />
        <!-- Create directory structures -->
        <mkdir dir="${targetdir}"/>
        <mkdir dir="${reportsdir}"/>
        <mkdir dir="${reportsdir}/raw/"/>
        <mkdir dir="${reportsdir}/html/"/>
    </target>

    <target name="compile" depends="clean, init, copy-support" description="Compile server side java code" >
        <javac srcdir="${sourcedir}"
           destdir="${wwwdir}/WEB-INF/classes"
            debug="true"
            debuglevel="lines,vars,source"
            source="1.6"
            excludes="**/client/*.java,**/*.xml">
            <classpath refid="classpath" />
            <compilerarg value="-Xlint"/>
        </javac>
        <!-- copy www class files to bin folder -->
    <copy todir="${targetdir}" >
        <fileset dir="${wwwdir}/WEB-INF/classes/com/petermac/claimsmanager/client" includes="*.class" />
    </copy>

    <copy todir="${targetdir}" >
        <fileset dir="${wwwdir}/WEB-INF/classes/com/petermac/claimsmanager/server/service" includes="*.class" />
    </copy>
    </target>

    <target name="gwt-compile" depends="init" description="Execute the GWT compiler on client-side code" >
        <!-- Invoke the GWT compiler -->
        <java classpathref="gwt.compile.class.path" classname="com.google.gwt.dev.GWTCompiler" fork="true" >
            <arg value="-out"/>
            <arg value="${gwt.output}"/>
            <arg value="com.petermac.claimsmanager.${app}"/>
        </java>
    </target>
    <target name="clean" depends="clean-compile-test" description="Cleans build system by removing directories created during build">
        <delete dir="${targetdir}"/>
        <mkdir dir="${targetdir}"/>
        <delete dir="${reportsdir}"/>
        <delete dir="${wwwdir}"/>
    </target>

    <target name="prepare-www-dir" depends="init" description="Copy files to ${wwwdir} directory">     

        <mkdir dir="${wwwdir}/WEB-INF/classes" />
        <mkdir dir="${wwwdir}/WEB-INF/lib" />

        <!-- copy all public files to $wwwdir -->
        <copy todir="${wwwdir}" >
            <fileset dir="${sourcedir}/com/petermac/${app}/public" />
        </copy>
        <!-- copy the gwt servlet JAR to /WEB-INF/lib -->
        <copy todir="${wwwdir}/WEB-INF/lib" file="${gwt.servlet.jar}" />

        <!-- copy web.xml to /WEB-INF -->
        <copy todir="${wwwdir}/WEB-INF/lib" file="${gwt.servlet.jar}" />

        <!-- copy the web.xml deployment descritpor -->
        <copy todir="${wwwdir}/WEB-INF/" file="${sourcedir}/web.xml" />
    </target>
       
    <!-- Copy relevant hibernate and spring files -->
    <target name="copy-support" depends="prepare-www-dir" description="Copy hibernate/spring support files">
        <copy todir="${wwwdir}/WEB-INF/lib" file="${postgresql.driver.jar}" />
        <copy todir="${wwwdir}/WEB-INF/lib" file="${hibernate3.jar}" />

        <!-- copy over the bulk of support jars -->
        <copy todir="${wwwdir}/WEB-INF/lib" >
            <fileset dir="${hibernate.dir}/" includes="*.jar" />
        </copy>
   
        <copy todir="${wwwdir}/WEB-INF/lib" >
            <fileset dir="${spring.dir}/" includes="*.jar" />
        </copy>

        <!-- copy the hibernate and spring config files -->
        <copy todir="${wwwdir}/WEB-INF/classes" >
            <fileset dir="${spring.conf.dir}/" includes="*.xml" />
        </copy>

        <copy todir="${wwwdir}/WEB-INF/classes" >
            <fileset dir="${hibernate.conf.dir}/" includes="*.xml" />
        </copy>

    </target>
    <target name="deploy" depends="compile,gwt-compile" description="Deploy the application">
        <war destfile="${app}.war" webxml="${wwwdir}/WEB-INF/web.xml">
            <fileset dir="${wwwdir}"/>
            <classes dir="${wwwdir}/WEB-INF/classes"/>
            <lib dir="${wwwdir}/WEB-INF/lib" />
        </war>
    </target>
    <!-- ////////////////////////// Test related targets /////////////////////////////////-->
   
    <target name="clean-compile-test" description="Cleans the classes deployed used during unit tests">
        <delete verbose="${TALK}">
            <fileset dir="${testdir}" includes="**/*.class" />
        </delete>
    </target>

    <target name="compile-tests" description="Compile unit tests">
        <javac srcdir="${testdir}"
         destdir="${targetdir}"
          verbose="${TALK}"
           classpathref="test.classpath">
        </javac>
    </target>
     
    <target name="run-tests" depends="compile-tests" description="Compiles and runs unit tests">
            <junit printsummary="yes" haltonfailure="true" showoutput="yes" >
                    <classpath refid="classpath" />
                    <classpath refid="test.classpath" />
                    <batchtest fork="yes" todir="${reportsdir}/raw/">
                    <formatter type="xml" />
                    <fileset dir="${testdir}" includes="**/AllTests.java" />
          </batchtest>
        </junit>
      </target>    

      <target name="test" depends="run-tests" description="Comiles tests, runs them and generates test results in report format">
        <junitreport todir="${reportsdir}">
            <fileset dir="${reportsdir}/raw/">
                <include name="TEST-*.xml"/>
            </fileset>
            <report format="frames" todir="${reportsdir}\html\"/>
        </junitreport>
      </target>

      <!-- end test related -->
    <!--
    <target name="package" depends="compile" description="Package up the project as a jar">
        <jar destfile="ClaimsManager.jar">
            <fileset dir="bin">
                <include name="**/*.class"/>
            </fileset>
            <fileset dir="src">
                <include name="**"/>
            </fileset>
            <fileset dir="test">
                <include name="**"/>
            </fileset>
        </jar>
    </target>
    -->

    <!--
    <target name="all" depends="package"/>
    -->
</project>

Feel free to suggest any ways to make this simpler and more automated.

  • Share/Bookmark

Public Key

—–BEGIN PGP PUBLIC KEY BLOCK—–
Version: GnuPG v1.4.9 (MingW32)

mQGiBEj1SQoRBACbRUMtyYFvFa81V7cnzbYJzSfk5MDuUdV0Wo+ckxKKRfW4Qf30
+ORIJeqzirJp9tOd8/uoPVnxNOK4LBKw47W+lHHLUYNMy2qByy7zVBXfg9EXuIrU
edebiwM92yODj/VoAxTjI1p5Mmr5fhFSSEo8yh7GTqg8g0j4jWPR+eZxywCgi78d
CZ6WmIS+tpNvEqrV/DwQUd0D/R9tyFMuwVKKOcyPxpekJ5RmKk8DDJ7cx6z0s6wM
kpx5qpL2QKhVp/3s7t9M40FT3ZmT2ERjJwZzncM8JMxDOK/vS8CRGlTd/JJIzWNj
8SOo55HCq1gJP8U01P1wU1AK9/7n+RcENOGvHEPvKfWweY8HuE8OwHkPGxkqT4og
1TNgA/97226C/NTf7MmOmV5y3yo5k5VUzGRjPpyvZIxIxnQJR4viquNEJfnW9BQT
kRw4J7qQePvcbYrvDWxHlJJzlIzQxbBUqVry4K79ByudQA8QaQAT+XJIMjjppgHz
rKWB6YVTqsSlfjASM9RqjfDCMZpefpjlq2hvJ2WzyLnYGyEJ+rRuUGV0ZXIgTWFj
IEdpb2xsYWZoZWFyZ2EgKEtleSBmb3IgbWFpbCBmcm9tIHBldGVyQHBldGVybWFj
LmNvbSAtIFBldGVyIE1hYyBBbmQgQXNzb2NpYXRlcykgPHBldGVyQHBldGVybWFj
LmNvbT6IZgQTEQIAJgUCSPVJCgIbIwUJCWYBgAYLCQgHAwIEFQIIAwQWAgMBAh4B
AheAAAoJEJlpD3yHCMV4/qYAn0WbPZejFQGgFi3g5IT2Q0D8u++xAJsGmFMdEwPm
zFi4mAEAbhfO+tuUr7kCDQRI9UkKEAgAhf491b6MaNOCp1qo9hjvX1NLQ1sORkI9
suP7PceRZfXuqc92GMXw8lYds9cPddtOBPpBZCaezxvRZHfERwiSWEVjEdwXyC5z
y8ys8L4jxaPS8YS3SnEjkg+1DCLRb5fry+jiSaFeC2YklFFopSxWiSJQow9+jIPF
hfvE4ZswP3EBx54SYC92sZgqfq/DcDcqlOp7gGAxHhxP+rdt4ow4aEzhdzyzNVpb
C26BwRWH6T1JtsBSiy0PoaxV2eVl3Fb93aHPVldtdk5p6Pqm03KAbowurFfLshK9
jyPuOyaM8cUSN+RXSgi846mXT0EhY6J4Ofb0rClm8maXwtSHpk8wBwADBQf/b4i6
oDa5K69S2tyERpxAPhSBPdUnYT0oxlZvj75Wp1SfBkmUy8O+1jONIE1+OhLslxke
WdFMmDrH8AiRU0q19bGEsKDqUWt58UV7GL26+QZbQWjhz7fWzI6ljftgshmXQozI
3725Y2AVQR3U4BaFNiFrJQECPYLB/yypf8OCsZjspERb+d4J7CXfk5mVkFFAOj7N
5UQv0u+dMVJAP3OCVdEibjXc/c4qPPxLUioAqN8MbixM1OzZDOH55K/oJdRoGyIG
mfWU1lToNDCSi7BSqXjPGC+DMDjFc4QfnBFJfV0301GvLshuw+b/r8qJNfxkYkk4
zK/sgbPlXPL032aM4ohPBBgRAgAPBQJI9UkKAhsMBQkJZgGAAAoJEJlpD3yHCMV4
JQMAnA21n/10YG9hXHrUEel1HTFcU+opAJ9KlShcMzJoLI5VVIqfJTa8y/GE+Q==
=L39p
—–END PGP PUBLIC KEY BLOCK—–

Click here to download this as key as a file

  • Share/Bookmark

Purrfect Java Solutions

Meet “Java”, a new addition to the PeterMac team.

java at 9 weeks

Although only 9 weeks old, she shows great focus in object oriented design (she chases any object that moves). She’s got an excellent grasp of string manipulation technniques and we have to agree that her display of experience in the J2SE (Sleeping and Eating) area is beyond expectations for one so young.

  • Share/Bookmark

Minister for misCommunication

A recent brain-fart by the Australian Minister for Communications, Helen Coonan, has exemplefied why Australia remains a relative technology backwater. She said that she expects people ought to be happy with existing Internet speeds.

“Well they ought to be in Sydney, Melbourne, Adelaide, Brisbane, certainly and Perth,” she said.

“They should be reasonably happy with their speed of broadband, if they have ADSL 2 Plus.

“There are nine providers that already provide these speeds.”

This outburst happened as a result of an announcement by Telstra (the 51% government owned body responsible for maintaining the telecomms infrastructure) that it was pulling out of a proposed fibre optic upgrade to existing networks.

Indeed there is access to ADSL 2+ in these cities but no thanks to Government support. The roll-out has been excruciatingly slow and is only available in higher population density areas. It (the ADSL2 network)has been taken on by a consortium of private companies with the previous threat of the Telstra upgrade having the potential to render their effort futile.

For a Minister of Communications to make such a generalised and uninformed comment smacks of a level of ignorance that can only come from some-one whos’ tenure in the role is transient. Be warned, your communications minister does not have the best interests of Australian Internet users at heart.

Statistics from the OECD show Australia in 18th place in terms of broadband take-up. Although this is not a reflection of Internet speeds, it is a reflection on the perceived cost/benefit available to Australian consumers. Get your act together Minister!

For more information check out this article by the Australian Broadcasting Corporation

  • Share/Bookmark