Ant

Inleiding

Voor Ant bestaan er op de Ant homepage prima tutorials. Op deze pagina vind je een voorbeeld build.xml uitgewerkt voor standaard taken zoals compileren, javadoc, junittesten en checkstyle. Verder is er een voorbeeld opgenomen van de samenwerking tussen Ant en Ivy

Properties

Om zoveel mogelijk harde paden te vermijden starten we met het definieren van een aantal properties:

<property name="dirs.source" value="${basedir}/src" />
<property name="dirs.test" value="${basedir}/test" />
<property name="dirs.build" value="${basedir}/build" />
<property name="dirs.dist" value="${basedir}/dist" />
<property name="dirs.config" value="${basedir}/toolconfigs" />
<property name="dirs.libs" value="${basedir}/libs" />
<property name="dirs.reports" value="${basedir}/reports" />
<property name="dirs.javadoc" value="${basedir}/reports/javadoc" />
<property name="dirs.junit" value="${basedir}/reports/junit" />
<property name="dirs.checkstyle" value="${basedir}/reports/checkstyle" />

Een van de meest opvallende properties is dirs.libs waarmee verwezen wordt naar een pad waar jars opgenomen kunnen worden waarna gerefereerd wordt vanuit de source code. Een alternatief voor het zelf opnemen van deze dependencies is het gebruik van een dependency manager zoals Maven of Ivy. In het lib-path van dit voorbeeld zijn de jars opgenomen van checkstyle en junit.

Compileren

Om te kunnen compileren is het praktisch een classpath op te zetten en eventuele andere plichtplegingen zoals het aanmaken van verschillende directories. Hiervoor gebruiken we twee aparte targets, namelijk init en compile, daarnaast definieren we een path voor het classpath:

<path id="base.classpath">
	<pathelement location="${dirs.build}" />
	<pathelement path="${java.class.path}" />
	<fileset dir="libs">
		<include name="**/*.jar" />
	</fileset>
</path>

<target name="init">
	<echo>Initializing timestamp, creating dirs</echo>
	<tstamp />
	<mkdir dir="${dirs.build}" />
</target>

<target name="compile" depends="init" description="Compile all of the source code">
	<echo>Compiling all the code</echo>
	<javac srcdir="${dirs.source};${dirs.test}" destdir="${dirs.build}" >
		<classpath refid="base.classpath"/>
	</javac>
</target>

Door het classpath als path te definieren kan in verschillende targets de definitie gebruikt worden via het refid.

Javadoc

Het uitdraaien van javadoc is betrekkelijk eenvoudig. Indien er veel externe dependencies zijn is het praktisch ook het classpath te koppelen aan dit target:

<target name="javadoc">
	<mkdir dir="${dirs.javadoc}" />
	<echo>Generate javadoc</echo>
	<javadoc sourcepath="${dirs.source}" destdir="${dirs.javadoc}" packagenames="*.*" />
</target>

Unittesten

Voor het gebruik van JUnit heeft Ant een specifieke taak om de testcases te runnen. Vervolgens zijn er nog andere tasks nodig om tot een opgemaakt report te komen:

<target name="junittests" depends="compile" description="Executing JUnit tests">
	<echo>Testing, testing, testing ... </echo>
	<mkdir dir="${dirs.junit}" />
	<junit haltonfailure="no" printsummary="yes" showoutput="yes">
		<classpath refid="base.classpath" />
		<formatter type="xml" />
		<batchtest todir="${dirs.junit}">
			<fileset dir="${dirs.build}">
				<include name="**/*Test.class" />
			</fileset>
		</batchtest>
	</junit>
	<junitreport todir="${dirs.junit}">
		<fileset dir="${dirs.junit}">
			<include name="TEST-*.xml" />
		</fileset>
		<report format="frames" todir="${dirs.junit}">
		</report>
	</junitreport>
</target>

Checkstyle

Het handmatig nalopen of je code voldoet aan de afgesproken codingguidelines is vervelend werk. Gelukkig is er Checkstyle die je handig aan je build-file kunt hangen:

<target name="checkstyle" description="Report of code convention violations">
	<mkdir dir="${dirs.checkstyle}" />
	<checkstyle config="${dirs.config}/ddoa_checks.xml">
		<fileset dir="${dirs.source}">
			<exclude name="**/*Test.java" />
			<include name="**/*.java" />
		</fileset>
		<formatter type="xml" tofile="${dirs.checkstyle}/checkstyle_report.xml" />
	</checkstyle>
	<xslt in="${dirs.checkstyle}/checkstyle_report.xml" out="${dirs.checkstyle}/index.checkstyle.html" style="${dirs.config}/checkstyle-noframes-sorted.xsl" />
</target>

Ivy

Vooral als je Maven lastig vindt of als je Ant wilt blijven gebruiken zonder je eigen lib-map te moeten administreren, is Ivy een handig hulpmiddel. Vooral in projecten waarbij Groovy of Grails gebruikt wordt steekt Ivy de kop op als dependency manager. Om Ivy te gebruiken zijn er verschillende files:

  • build.xml
  • ivy.xml
  • ivysettings.xml

Ivy - build.xml

Om Ivy in je Ant build file te gebruiken kun je Ivy installeren, maar ook Ant de laatste versie van Ivy laten downloaden (je hebt toch een internetverbinding nodig voor het downloaden van de dependencies):

<target name="download-ivy" unless="offline">
       <available file="${ivy.jar.file}" property="ivy.available"/>
       <antcall target="-download-ivy"/>
</target>

<target name="-download-ivy" unless="ivy.available">
       <mkdir dir="${ivy.jar.dir}"/>
       <!-- download Ivy from web site so that it can be used even without any special installation -->
       <get src="http://www.apache.org/dist/ant/ivy/${ivy.install.version}/apache-ivy-${ivy.install.version}-bin.zip"
             dest="${ivy.home}/ivy.zip" usetimestamp="true" verbose="true"/>
       <unzip src="${ivy.home}/ivy.zip" dest="${ivy.jar.dir}">
            <patternset>
                <include name="**/*.jar"/>
            </patternset>
            <mapper type="flatten"/>
       </unzip>
</target>

<target name="init-ivy" depends="download-ivy" unless="ivy.lib.path">
        <path id="ivy.lib.path">
            <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
        </path>
        <taskdef resource="org/apache/ivy/ant/antlib.xml"
                 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
</target>


<property name="lib.dir" value="${basedir}/lib"/>

<target name="-resolve" description="--> Retrieve dependencies with ivy" depends="init-ivy">
       <ivy:retrieve pattern="${lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
</target>

Maak je eigen targets afhanjelijk van de -resolve target en definieer je exacte dependencies in ivy.xml.

Ivy - ivy.xml

Deze file bevat de lijst met dependencies:

<ivy-module version="2.0">
    <info organisation="org.example" module="MrMatching"/>
    <configurations
            defaultconfmapping="build->default;compile->compile(*),master(*);test,runtime->runtime(*),master(*)">
        <conf name="build"/>
        <conf name="compile"/>
        <conf name="test" extends="compile"/>
        <conf name="runtime" extends="compile"/>
    </configurations>
    <dependencies>
        <dependency org="org.grails" name="grails-bootstrap" rev="1.1.2" conf="build"/>
        <dependency org="org.grails" name="grails-scripts" rev="1.1.2" conf="build"/>
        <dependency org="org.grails" name="grails-gorm" rev="1.1.2" conf="compile"/>
        <dependency org="org.grails" name="grails-web" rev="1.1.2" conf="compile"/>
        <dependency org="org.grails" name="grails-test" rev="1.1.2" conf="test"/>
        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.5.5" conf="runtime"/>
        <dependency org="opensymphony" name="oscache" rev="2.4" conf="runtime">
            <exclude org="javax.jms" module="jms" name="*" type="*" ext="*" conf="" matcher="exact"/>
            <exclude org="commons-logging" module="commons-logging" name="*" type="*" ext="*" conf="" matcher="exact"/>
            <exclude org="javax.servlet" module="servlet-api" name="*" type="*" ext="*" conf="" matcher="exact"/>
        </dependency>
        <dependency org="org.tmatesoft.svnkit" name="svnkit" rev="1.2.3.5521" conf="build"/>
        <dependency org="hsqldb" name="hsqldb" rev="1.8.0.5" conf="runtime"/>
        <dependency org="net.sf.ehcache" name="ehcache" rev="1.5.0" conf="runtime"/>
    </dependencies>
</ivy-module>

Ivy - ivysettings.xml

Ivy moet nog wel even weten waar alle dependencies vandaan moeten komen, hiervoor is de ivysettings.xml:

<ivysettings>
    <settings defaultResolver="codehaus-plus"/>
    <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
    <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
    <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
    <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
    <resolvers>
        <chain name="codehaus-plus" dual="true">
            <ibiblio name="codehaus-snapshots" root="http://snapshots.repository.codehaus.org" m2compatible="true"
                     changingPattern=".*SNAPSHOT"/>
            <ibiblio name="codehaus" root="http://repository.codehaus.org" m2compatible="true"/>
            <ibiblio name="javanet" root="http://download.java.net/maven/2/" m2compatible="true"/>
            <resolver ref="public"/>
        </chain>
    </resolvers>
</ivysettings>

Labels

ant ant Delete
ivy ivy Delete
dependency-manager dependency-manager Delete
junit junit Delete
javadoc javadoc Delete
checkstyle checkstyle Delete
groovy groovy Delete
grails grails Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.