Salta ai contenuti

Cheat Sheet di Apache Ant

Cheat Sheet di Apache Ant

Installazione

PiattaformaComando
Ubuntu/Debiansudo apt update && sudo apt install ant
RHEL/CentOS/Fedorasudo yum install ant or sudo dnf install ant
Arch Linuxsudo pacman -S apache-ant
macOS (Homebrew)brew install ant
Windows (Chocolatey)choco install ant
Manual (All Platforms)Download from apache.org, extract, set ANT_HOME and add bin/ to PATH
Prerequisiti: È richiesto Java JDK 8+. Impostare JAVA_HOMEvariabile di ambiente.

Comandi di Base

ComandoDescrizione
ant -versionVisualizza la versione di Ant, la versione di Java e le informazioni del sistema operativo
antEsegui il target predefinito specificato in build.xml
ant compileEsegui il target “compile” da build.xml
ant cleanEsegui il target “clean” (tipicamente rimuove gli artefatti di build)
ant -projecthelpElenca tutti i target disponibili con le relative descrizioni
ant -pForma breve di -projecthelp
ant -f custom-build.xmlUtilizzare un file di build alternativo invece di build.xml
ant -buildfile mybuild.xml compileSpecificare il file di build e il target da eseguire
ant -verbose compileMostra informazioni dettagliate di esecuzione
ant -v testForma breve di -verbose
ant -debug packageVerbosità massima per la risoluzione dei problemi
ant -d deployForma breve di -debug
ant -quiet testOutput minimo, mostra solo gli errori
ant -q buildForma breve di -quiet
ant -logfile build.log compileReindirizza l’output al file di log specificato
ant -l output.log testForma breve di -logfile

Utilizzo Avanzato

ComandoDescrizione
ant -Denv=production deployImposta il valore della proprietà dalla riga di comando
ant -Dversion=1.2.3 -Dbuild.number=456 packageImposta più proprietà
ant -propertyfile custom.properties buildCarica proprietà da file esterno
ant -findCerca nelle directory genitore il file build.xml
ant -sForma breve di -find
ant -keep-going testContinuare l’esecuzione di target indipendenti dopo un errore
ant -k testForma abbreviata di -keep-going
ant -diagnosticsVisualizza informazioni di sistema e dettagli di configurazione
ant -listener org.apache.tools.ant.listener.Log4jListener compileAggiungi listener personalizzato per evento di build
ant -logger org.apache.tools.ant.NoBannerLogger compileUtilizzare un’implementazione personalizzata di logger
ant -inputhandler org.apache.tools.ant.input.SecureInputHandler deployUtilizzare un gestore di input personalizzato per un input sicuro
ant -noclasspath compileIgnora la variabile di ambiente CLASSPATH
ant -autoproxy downloadConfigura automaticamente le impostazioni del proxy Java
ant -lib /path/to/jars compileAggiungi directory di JARs al classpath di Ant
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor buildAbilitare l’esecuzione di attività parallele
ant compile test packageEsegui più target in sequenza
ant -Dskip.tests=true packageSalta condizionalmente le attività in base alla proprietà

Configurazione

Struttura Base di build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="build" basedir=".">
    
    <!-- Properties -->
    <property name="src.dir" value="src"/>
    <property name="build.dir" value="build"/>
    <property name="dist.dir" value="dist"/>
    <property name="lib.dir" value="lib"/>
    
    <!-- Classpath -->
    <path id="classpath">
        <fileset dir="${lib.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </path>
    
    <!-- Clean target -->
    <target name="clean" description="Remove build artifacts">
        <delete dir="${build.dir}"/>
        <delete dir="${dist.dir}"/>
    </target>
    
    <!-- Init target -->
    <target name="init" depends="clean">
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${dist.dir}"/>
    </target>
    
    <!-- Compile target -->
    <target name="compile" depends="init" description="Compile source code">
        <javac srcdir="${src.dir}" 
               destdir="${build.dir}"
               classpathref="classpath"
               includeantruntime="false"
               debug="true"
               source="11"
               target="11"/>
    </target>
    
    <!-- Build target -->
    <target name="build" depends="compile" description="Build JAR file">
        <jar destfile="${dist.dir}/${ant.project.name}.jar" 
             basedir="${build.dir}">
            <manifest>
                <attribute name="Main-Class" value="com.example.Main"/>
            </manifest>
        </jar>
    </target>
    
</project>

File build.properties

# Project configuration
project.name=MyApplication
project.version=1.0.0

# Directory structure
src.dir=src/main/java
test.dir=src/test/java
resources.dir=src/main/resources
build.dir=target/classes
dist.dir=dist

# Compiler settings
java.source.version=11
java.target.version=11
javac.debug=true
javac.deprecation=true

# Dependencies
lib.dir=lib

Caricamento delle Proprietà in build.xml

<property file="build.properties"/>
<property file="build-${env}.properties"/>
<property environment="env"/>

Filesets e Pattern Comuni

<!-- Include all Java files -->
<fileset dir="${src.dir}" includes="**/*.java"/>

<!-- Exclude test files -->
<fileset dir="${src.dir}">
    <include name="**/*.java"/>
    <exclude name="**/*Test.java"/>
</fileset>

<!-- Pattern sets for reuse -->
<patternset id="source.patterns">
    <include name="**/*.java"/>
    <include name="**/*.properties"/>
    <exclude name="**/*Test.java"/>
</patternset>

Casi d’Uso Comuni

Caso d’Uso: Compilazione di un’Applicazione Java Completa

# Clean previous builds
ant clean

# Compile, test, and package in one command
ant compile test package

# Build with specific environment properties
ant -Denv=production -propertyfile prod.properties package

# Create distribution with documentation
ant clean compile test package javadoc dist

Target di build.xml:

<target name="test" depends="compile">
    <junit printsummary="yes" haltonfailure="yes">
        <classpath>
            <path refid="classpath"/>
            <pathelement location="${build.dir}"/>
        </classpath>
        <batchtest fork="yes">
            <fileset dir="${test.dir}">
                <include name="**/*Test.java"/>
            </fileset>
        </batchtest>
    </junit>
</target>

<target name="javadoc">
    <javadoc sourcepath="${src.dir}" 
             destdir="${dist.dir}/docs"
             packagenames="com.example.*"/>
</target>

Caso d’Uso: Creazione di File WAR per Applicazione Web

# Build and package web application
ant clean compile war

# Deploy to application server
ant -Dserver.path=/opt/tomcat/webapps deploy

Configurazione di build.xml:

<target name="war" depends="compile">
    <war destfile="${dist.dir}/${project.name}.war" 
         webxml="web/WEB-INF/web.xml">
        <classes dir="${build.dir}"/>
        <lib dir="${lib.dir}"/>
        <fileset dir="web">
            <include name="**/*.jsp"/>
            <include name="**/*.html"/>
            <include name="**/*.css"/>
            <include name="**/*.js"/>
        </fileset>
    </war>
</target>

<target name="deploy" depends="war">
    <copy file="${dist.dir}/${project.name}.war" 
          todir="${server.path}"/>
</target>

Caso d’Uso: Compilazione di Progetto Multi-Modulo

# Build all modules in parallel
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor build-all

# Build specific module
ant -Dmodule=core build-module

# Build and run integration tests
ant build-all integration-test

build.xml con sottoprogetti:

<target name="build-all">
    <subant target="build">
        <fileset dir="." includes="*/build.xml"/>
    </subant>
</target>

<target name="build-module">
    <ant dir="${module}" target="build" inheritAll="false"/>
</target>

Caso d’Uso: Build Condizionali con Verifica delle Proprietà

# Skip tests during build
ant -Dskip.tests=true package

# Build only if sources changed
ant -Dincremental=true compile

# Production build with optimizations
ant -Doptimize=true -Ddebug=false production-build

build.xml con condizioni:

<target name="compile">
    <javac srcdir="${src.dir}" 
           destdir="${build.dir}"
           debug="${debug}"
           optimize="${optimize}">
        <classpath refid="classpath"/>
    </javac>
</target>

<target name="test" unless="skip.tests">
    <junit printsummary="yes">
        <classpath>
            <path refid="classpath"/>
            <pathelement location="${build.dir}"/>
        </classpath>
        <batchtest>
            <fileset dir="${test.dir}" includes="**/*Test.java"/>
        </batchtest>
    </junit>
</target>

<target name="package" depends="compile,test">
    <jar destfile="${dist.dir}/${ant.project.name}.jar" 
         basedir="${build.dir}"/>
</target>

Caso d’Uso: Migrazione e Distribuzione Database

# Run database migrations
ant -propertyfile db-config.properties db-migrate

# Deploy application with database updates
ant -Denv=staging db-migrate deploy

# Rollback database changes
ant -Dversion=1.2.0 db-rollback

build.xml con task SQL:

<target name="db-migrate">
    <sql driver="${db.driver}"
         url="${db.url}"
         userid="${db.user}"
         password="${db.password}"
         src="migrations/migrate-${version}.sql"
         print="yes"
         output="migration.log"/>
</target>

<target name="db-rollback">
    <sql driver="${db.driver}"
         url="${db.url}"
         userid="${db.user}"
         password="${db.password}"
         src="migrations/rollback-${version}.sql"/>
</target>

Migliori Pratiche

  • Utilizzare file di proprietà per la configurazione: Separare le impostazioni specifiche dell’ambiente dalla logica di build. Caricare le proprietà con <property file="build.properties"/> to keep build.xml clean and reusable.

  • Define meaningful target descriptions: Add descrizione attributes to public targets for better ant -aiutoprogetto output. This serves as built-in documentation for your build process.

  • Leverage target dependencies: Use dipende attribute to establish build order and avoid redundant task execution. Ant automatically handles dependency resolution.

  • Set includeantruntime="false" in javac tasks: Prevents Ant runtime libraries from polluting your application classpath, avoiding potential conflicts and reducing JAR size.

  • Use filesets and pattern sets for flexibility: Define reusable file patterns with <insiemedimodelli> and reference them in multiple targets. This makes maintenance easier and reduces duplication.

  • Implement incremental builds: Use <finoadata> conditions to skip compilation when source files haven’t changed, significantly speeding up development builds.

  • Version control your build files: Include build.xml, property files, and custom tasks in version control. Exclude generated directories like build/ and dist/ using .ignoragit.

  • Use macros for repeated task sequences: Define <definizionemacro> elements for common operations performed across multiple modules or targets, promoting DRY principles.

  • Separate concerns with imported build files: Split large build files into logical components (build-comune.xml, test-build.xml) e importarli per migliorare la manutenibilità.

  • Documentare la logica complessa con commenti: Utilizzare commenti XML per spiegare la logica di build non ovvia, l’utilizzo delle proprietà e le dipendenze, soprattutto in progetti condivisi o legacy.

Risoluzione dei problemi

ProblemaSoluzione
BUILD FAILED: build.xml does not existRun ant -find to search parent directories, or specify file with ant -f path/to/build.xml
Unable to locate tools.jarSet JAVA_HOME to JDK (not JRE) directory. Verify with echo $JAVA_HOME and ensure it points to JDK installation
ClassNotFoundException for custom tasksAdd JAR to Ant’s classpath using -lib option: ant -lib /path/to/jars compile or use <taskdef> with correct classpath
Compilation fails with encoding errorsAdd encoding="UTF-8" attribute to <javac> task: <javac srcdir="${src.dir}" encoding="UTF-8"/>
Out of memory during buildIncrease heap size: export ANT_OPTS="-Xmx1024m -Xms512m" (Linux/Mac) or set ANT_OPTS=-Xmx1024m (Windows)
Target not found errorVerify target name with ant -projecthelp. Check for typos and ensure target is defined in active build file
Circular dependency detectedReview depends attributes in targets. Ant cannot resolve circular references - redesign target dependencies
Permission denied when writing filesVerificare i permessi della directory e assicurarsi che Ant abbia accesso in scrittura. Eseguire con privilegi utente appropriati o modificare la proprietà della directory
fork="true" required but task failsSome tasks (junit, java) require forking. Ensure fork="true" is set and JAVA_HOME points to valid JDK
Properties not being overriddenProperties are immutable in Ant - first definition wins. Set properties via command line (-D) before build file loads them
Slow builds with large filesetsUse <uptodate> conditions for incremental builds. Enable parallel execution with -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor
JAR file manifest not correctUse <manifest> element within <jar> task to specify Main-Class and other attributes explicitly

Riferimento Attività Ant Comuni

AttivitàDescrizioneEsempio
<javac>Compilare file sorgente Java<javac srcdir="src" destdir="build" includeantruntime="false"/>
<jar>Crea archivio JAR<jar destfile="dist/app.jar" basedir="build"/>
<war>Creare archivio WAR<war destfile="dist/app.war" webxml="web/WEB-INF/web.xml"/>
<copy>Copia file o directory<copy todir="backup"><fileset dir="src"/></copy>
<delete>Elimina file o directory<delete dir="build"/>
<mkdir>Crea directory<mkdir dir="dist"/>
<echo>Stampa messaggio<echo message="Building version ${version}"/>
<exec>Esegui comando di sistema<exec executable="git" args="rev-parse HEAD"/>
<junit>Esegui test JUnit<junit printsummary="yes" fork="yes"/>
<zip>Crea archivio ZIP<zip destfile="dist/src.zip" basedir="src"/>
<sql>Esegui istruzioni SQL<sql driver="${db.driver}" url="${db.url}" src="schema.sql"/>