Vai al contenuto

Cheat Sheet di Apache Ant

Installazione

Piattaforma Comando
Ubuntu/Debian sudo apt update && sudo apt install ant
RHEL/CentOS/Fedora sudo yum install ant or sudo dnf install ant
Arch Linux sudo 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

Comando Descrizione
ant -version Visualizza la versione di Ant, la versione di Java e le informazioni del sistema operativo
ant Esegui il target predefinito specificato in build.xml
ant compile Esegui il target "compile" da build.xml
ant clean Esegui il target "clean" (tipicamente rimuove gli artefatti di build)
ant -projecthelp Elenca tutti i target disponibili con le relative descrizioni
ant -p Forma breve di -projecthelp
ant -f custom-build.xml Utilizzare un file di build alternativo invece di build.xml
ant -buildfile mybuild.xml compile Specificare il file di build e il target da eseguire
ant -verbose compile Mostra informazioni dettagliate di esecuzione
ant -v test Forma breve di -verbose
ant -debug package Verbosità massima per la risoluzione dei problemi
ant -d deploy Forma breve di -debug
ant -quiet test Output minimo, mostra solo gli errori
ant -q build Forma breve di -quiet
ant -logfile build.log compile Reindirizza l'output al file di log specificato
ant -l output.log test Forma breve di -logfile
## Utilizzo Avanzato
Comando Descrizione
ant -Denv=production deploy Imposta il valore della proprietà dalla riga di comando
ant -Dversion=1.2.3 -Dbuild.number=456 package Imposta più proprietà
ant -propertyfile custom.properties build Carica proprietà da file esterno
ant -find Cerca nelle directory genitore il file build.xml
ant -s Forma breve di -find
ant -keep-going test Continuare l'esecuzione di target indipendenti dopo un errore
ant -k test Forma abbreviata di -keep-going
ant -diagnostics Visualizza informazioni di sistema e dettagli di configurazione
ant -listener org.apache.tools.ant.listener.Log4jListener compile Aggiungi listener personalizzato per evento di build
ant -logger org.apache.tools.ant.NoBannerLogger compile Utilizzare un'implementazione personalizzata di logger
ant -inputhandler org.apache.tools.ant.input.SecureInputHandler deploy Utilizzare un gestore di input personalizzato per un input sicuro
ant -noclasspath compile Ignora la variabile di ambiente CLASSPATH
ant -autoproxy download Configura automaticamente le impostazioni del proxy Java
ant -lib /path/to/jars compile Aggiungi directory di JARs al classpath di Ant
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor build Abilitare l'esecuzione di attività parallele
ant compile test package Esegui più target in sequenza
ant -Dskip.tests=true package Salta 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

Problema Soluzione
BUILD FAILED: build.xml does not exist Run ant -find to search parent directories, or specify file with ant -f path/to/build.xml
Unable to locate tools.jar Set JAVA_HOME to JDK (not JRE) directory. Verify with echo $JAVA_HOME and ensure it points to JDK installation
ClassNotFoundException for custom tasks Add JAR to Ant's classpath using -lib option: ant -lib /path/to/jars compile or use <taskdef> with correct classpath
Compilation fails with encoding errors Add encoding="UTF-8" attribute to <javac> task: <javac srcdir="${src.dir}" encoding="UTF-8"/>
Out of memory during build Increase heap size: export ANT_OPTS="-Xmx1024m -Xms512m" (Linux/Mac) or set ANT_OPTS=-Xmx1024m (Windows)
Target not found error Verify target name with ant -projecthelp. Check for typos and ensure target is defined in active build file
Circular dependency detected Review depends attributes in targets. Ant cannot resolve circular references - redesign target dependencies
Permission denied when writing files Verificare 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 fails Some tasks (junit, java) require forking. Ensure fork="true" is set and JAVA_HOME points to valid JDK
Properties not being overridden Properties are immutable in Ant - first definition wins. Set properties via command line (-D) before build file loads them
Slow builds with large filesets Use <uptodate> conditions for incremental builds. Enable parallel execution with -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor
JAR file manifest not correct Use <manifest> element within <jar> task to specify Main-Class and other attributes explicitly
## Riferimento Attività Ant Comuni
Attività Descrizione Esempio
<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"/>