Pular para o conteúdo

Folha de Dicas do Apache Ant

PlataformaComando
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

Instalação

ComandoDescrição
ant -versionExibir versão do Ant, versão do Java e informações do sistema operacional
antExecutar o target padrão especificado no build.xml
ant compileExecute o destino “compile” a partir do build.xml
ant cleanExecute o alvo “clean” (tipicamente remove artefatos de compilação)
ant -projecthelpListe todos os alvos disponíveis com descrições
ant -pForma abreviada de -projecthelp
ant -f custom-build.xmlUsar arquivo de build alternativo em vez de build.xml
ant -buildfile mybuild.xml compileEspecifique o arquivo de build e o destino para executar
ant -verbose compileMostrar informações detalhadas de execução
ant -v testForma abreviada de -verbose
ant -debug packageVerbosidade máxima para solução de problemas
ant -d deployForma abreviada de -debug
ant -quiet testSaída mínima, mostrar apenas erros
ant -q buildForma abreviada de -quiet
ant -logfile build.log compileRedirecionar saída para arquivo de log especificado
ant -l output.log testForma abreviada de -logfile
ComandoDescrição
----------------------
ant -Denv=production deployDefinir valor de propriedade na linha de comando
ant -Dversion=1.2.3 -Dbuild.number=456 packageDefinir múltiplas propriedades
ant -propertyfile custom.properties buildCarregar propriedades de arquivo externo
ant -findProcurar diretórios pai por build.xml
ant -sForma abreviada de -find
ant -keep-going testContinuar executando alvos independentes após falha
ant -k testForma abreviada de -keep-going
ant -diagnosticsExibir informações do sistema e detalhes de configuração
ant -listener org.apache.tools.ant.listener.Log4jListener compileAdicionar ouvinte de evento de compilação personalizado
ant -logger org.apache.tools.ant.NoBannerLogger compileUsar implementação de logger personalizado
ant -inputhandler org.apache.tools.ant.input.SecureInputHandler deployUse manipulador de entrada personalizado para entrada segura
ant -noclasspath compileIgnorar variável de ambiente CLASSPATH
ant -autoproxy downloadConfigurar automaticamente as configurações de proxy do Java
ant -lib /path/to/jars compileAdicionar diretório de JARs ao classpath do Ant
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor buildHabilitar execução paralela de tarefas
ant compile test packageExecutar múltiplos alvos em sequência
ant -Dskip.tests=true packageIgnorar tarefas condicionalmente com base em propriedade

Comandos Básicos

<?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>

Uso Avançado

# 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

Configuração

Estrutura Básica do build.xml

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

Arquivo build.properties

<!-- 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>

Carregando Propriedades no build.xml

# 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

Conjuntos de Arquivos e Padrões Comuns

<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>

Casos de Uso Comuns

Caso de Uso: Compilação Completa de Aplicação Java

# Build and package web application
ant clean compile war

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

Targets do 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 de Uso: Criação de Arquivo WAR para Aplicação Web

# 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

Configuração do build.xml:

<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 de Uso: Compilação de Projeto Multi-Módulo

# 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 com subprojetos:

<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 de Uso: Compilações Condicionais com Verificação de Propriedades

# 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 com condições:

<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>

Caso de Uso: Migração e Implantação de Banco de Dados

` to keep build.xml clean and reusable.

  • Define meaningful target descriptions: Add descrição attributes to public targets for better ant -ajudaprojeto output. This serves as built-in documentation for your build process.

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

  • Set includeantruntime="falso" 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 <conjuntodepadrões> and reference them in multiple targets. This makes maintenance easier and reduces duplication.

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

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

  • Use macros for repeated task sequences: Define <definirmacrô> 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 (construção-comum.xml, teste-construção.xml) e importá-los para melhorar a manutenibilidade.

  • Documentar lógica complexa com comentários: Use comentários XML para explicar lógica de construção não óbvia, uso de propriedades e dependências, especialmente em projetos compartilhados ou legados.

Resolução de Problemas

ProblemaSolução
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 filesVerifique as permissões do diretório e garanta que o Ant tenha acesso de gravação. Execute com privilégios de usuário apropriados ou ajuste a propriedade do diretório
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

Referência de Tarefas Comuns do Ant

TarefaDescriçãoExemplo
<javac>Compilar arquivos de origem Java<javac srcdir="src" destdir="build" includeantruntime="false"/>
<jar>Criar arquivo JAR<jar destfile="dist/app.jar" basedir="build"/>
<war>Criar arquivo WAR<war destfile="dist/app.war" webxml="web/WEB-INF/web.xml"/>
<copy>Copiar arquivos ou diretórios<copy todir="backup"><fileset dir="src"/></copy>
<delete>Excluir arquivos ou diretórios<delete dir="build"/>
<mkdir>Criar diretório<mkdir dir="dist"/>
<echo>Imprimir mensagem<echo message="Building version ${version}"/>
<exec>Executar comando de sistema<exec executable="git" args="rev-parse HEAD"/>
<junit>Executar testes JUnit<junit printsummary="yes" fork="yes"/>
<zip>Criar arquivo ZIP<zip destfile="dist/src.zip" basedir="src"/>
<sql>Executar instruções SQL<sql driver="${db.driver}" url="${db.url}" src="schema.sql"/>