Ant - Argo Navis
Transcrição
Ant - Argo Navis
Abaporu @ JavaONE 2003 Como construir um Ambiente de desenvolvimento Java com Helder da Rocha ([email protected]) JEdit e Ant argonavis.com.br Objetivos argonavis.com.br Propor uma alternativa leve e barata para desenvolvimento de aplicações Java integradas com XML, HTML, JSP, etc. Apresentar o JEdit e principais plug-ins Apresentar o Ant e principais recursos Mostrar como manter um projeto com JEdit, Ant e outras ferramentas open-source Esta palestra é parcialmente baseada no artigo "Seu Ambiente Java Completo", por Helder da Rocha, Java Magazine, no. 3 2 argonavis.com.br JEdit? JEdit é um editor de textos desenvolvido como um projeto open-source iniciado por Slava Pestov É um projeto maduro que está em desenvolvimento há mais de 5 anos Supera vários editores e ambientes de desenvolvimento comerciais em relação a recursos e facilidade de uso Roda em qualquer plataforma Java Possui lunguagem de macro e API para plug-ins Altamente configurável e extensível Faz auto-endentação e code-highlight para mais de 80 linguagens 3 Só um editor de textos? À primeira vista, o JEdit parece apenas mais um editor de textos com algumas facilidades para edição de código argonavis.com.br Cores para palavras-chave Endentação automática Combinação de pares de chaves e parênteses 4 JEdit + plug-ins + Ant + J2SDK = IDE Usando seus plug-ins, J2SDK, Ant, CVS e outras ferramentas gratuitas, o JEdit torna-se um poderoso, porém leve, ambiente de desenvolvimento integrado Buffer Tabs Ant Farm XML e CodeAid argonavis.com.br Project Viewer XML, XSLT Console Error List 5 JEdit IDE: Receita de bolo Ingredientes Plataforma desktop compatível com Java: Windows, Mac, Linux, Solaris, AIX, etc. J2SDK mais recente (java.sun.com) JEdit mais recente (www.jedit.org) Apache Ant mais recente (ant.apache.org) Conexão internet ou JARs de plug-ins do JEdit argonavis.com.br Procedimento 1) 2) 3) 4) 5) 6) Instale o J2SDK Configure as variáveis de ambiente (JAVA_HOME) Abra o ZIP do Ant e inclua o ANT_HOME/bin no PATH Execute o JAR de instalação do JEdit Instale os plug-ins desejados (incluindo o AntFarm) Configure os plug-ins 6 Instalação e teste do J2SDK argonavis.com.br O Java 2 SDK oferece um ambiente de desenvolvimento Java com ferramentas que executam através da linha de comando Para instalar, siga as instruções referentes ao seu sistema operacional e lembre-se do local de instalação, que é o seu "Java Home" Configure as seguintes variáveis de ambiente JAVA_HOME: local de instalação do J2SDK PATH: acrescente $JAVA_HOME/bin (Unix) ou %JAVA_HOME%\bin no seu PATH Para testar, execute "javac" em qualquer janela de terminal 7 Instalação e teste do Ant Abra o ZIP do Ant e associe o diretório de instalação à variável de ambiente ANT_HOME Para testar o Ant e as variáveis de ambiente, execute "ant" em qualquer janela de terminal O resultado da execução deve ser: argonavis.com.br Buildfile: build.xml does not exist! Build failed Se o comando não for reconhecido pelo sistema, verifique se a instalação realmente aconteceu, e se $ANT_HOME/bin (ou %ANT_HOME%\bin) está no PATH: execute o caminho completo $ANT_HOME/bin/ant ANT_HOME foi definido corretamente: execute o caminho completo /local/da/instalacao/bin/ant 8 Espaço de Ambiente: Windows 98/ME Em ambientes Windows domésticos antigos (ME, 98) a execução do Ant pode causar um erro de "falta de espaço de ambiente" Esses sistemas só reservam 256 bytes para guardar variáveis de ambiente Para aumentar o espaço de ambiente, edite o arquivo c:\config.sys e acrescente no final, a linha: argonavis.com.br shell=c:\command.com /e:8192 /p Isto aumentará o espaço para 8kb, o que é suficiente para rodar o Ant e várias outras aplicações que usam muito espaço de ambiente 9 Instalação e execução do JEdit Instale o JEdit clicando no arquivo JAR baixado do site www.jedit.org. Se isto não funcionar, execute argonavis.com.br > java -jar jeditInstall.jar A instalação é simples. Basta seguir os passos indicados na janela No Windows, o JEdit criará por default ícones na área de trabalho e menu de aplicações Nos sistemas Unix, o JEdit poderá ser executado em linha de comando, usando: > jedit & ou Antes de começar a escrever, salve o arquivo com a extensão desejada (.xml, .java, .cpp) para que o JEdit reconheça o tipo de arquivo. 10 Instalação de plug-ins O JEdit, sem plug-ins, é um simples editor de textos Com Plug-ins, ele é comparável a um sofisticado ambiente de desenvolvimento integrado (IDE) Há duas formas de instalar plug-ins Baixar os JARs e copiá-los para o diretório jars da instalação JEdit ou do perfil do usuário (diretório .jedit) Em tempo real (com conexão Internet) argonavis.com.br A segunda forma é mais segura e evita erros Somente plug-ins compatíveis com a versão do JEdit aparecem na lista No download, plug-ins e suas dependências são instalados Use Plugins / Plugin Manager Remover Atualizar versão Instalar 11 Sugestão de plug-ins Existe uma quantidade enorme de plug-ins, para as mais variadas finalidades Não instale todos pois alguns podem causar conflitos Leia a descrição e marque o plug-in desejado argonavis.com.br Alguns plug-ins úteis Console Error List Ant Farm Buffer Tabs JSwat Project Viewer JBrowse XML JavaStyle Dot Complete Ant Helper Templates XML Indenter JDiff JCompiler XSLT 12 Plug-in bugs Embora usem uma API padrão do JEdit, os plug-ins são desenvolvidos por equipes independentes argonavis.com.br A integração entre Plug-ins nem sempre é perfeita Alguns plug-ins podem causar conflitos com outros existentes A solução é ler a mensagem de erro e tentar consertar o problema, ou desinstalar o plug-in defeituoso Um problema comum é a falta do tools.jar, que contém o compilador javac Solução: copie o tools.jar encontrado no diretório lib/ da instalação do J2SDK para o diretório jars da instalação do JEdit 13 Docking argonavis.com.br Alguns plug-ins possuem interface para interação com o usuário A interface por default aparece como uma janela flutuante. Para plug-ins usados com freqüência, pode ser mais cômodo posicioná-la na janela principal Para configurar o docking, selecione o menu Global Options / Docking e escolha a configuração desejada Sugestões de docking: Console e ErrorList: bottom AntFarm e JBrowse: left Project Viewer e JSwat: right 14 Configuração do JEdit e plug-ins argonavis.com.br Várias cónfigurações permitem tornar o JEdit mais amigável para o seu ambiente de desenvolvimento Vários plug-ins requerem (ou ficam mais amigáveis) com alguma configuração Para configurar o JEdit e plug-ins, selecione o menu Utilities/Global Options na interface do JEdit Configurações básicas Tamanho da endentação (def. 8): Editing / Tab Width Números das linhas: Gutter / Line Numbering Proxies HTTP: Proxy Servers Tamanho do texto: Text Area / Text Font 15 Console Um dos plug-ins mais úteis é o Console Reproduz a console de execução, compilação e outras operações dentro do ambiente do JEdit Permite que saída dos aplicativos seja utilizada por outros plug-ins (por exemplo: Error List) argonavis.com.br Prompt do Console Por default, Console aparece em uma janela flutuante. Se usar docking, é preciso tomar alguns cuidados com aplicativos que não terminam Há um bug que pode impedir o término da execução (isto irá acumular processos tornando o JEdit lento) Execute tarefas desse tipo em janelas flutuantes. 16 Buffer Tabs Buffer Tabs permitem trocar a forma de seleção dos buffers de texto por tabs. Para isto é preciso 1) Remover o "Buffer Switcher", instalado por default 2) Configurar "Buffer Tabs" como default Buffer Tabs 2) Marcar argonavis.com.br 1) Desmarcar 3) Selecionar Plug-in 17 Error List argonavis.com.br Error List integra-se com o plug-in Console, e filtra erros de compilação, validação XML, etc. O resultado é apresentado em uma janela que responde a eventos e permite saltar diretamente à página e linha onde ocorreu o erro 18 Configuração de ErrorList argonavis.com.br Error List acomoda-se bem no mesmo espaço que o Console (use docking "bottom" para ambos) Para que as mensagens de erro apareçam logo após a compilação/validação, configure o Error List com a opção "Automatically Display on Error" 19 Project Viewer O Project Viewer permite ter diferentes ambientes de trabalho para cada projeto Ao selecionar um projeto existente, todos os arquivos abertos na última sessão são lembrados Novos arquivos podem ser automaticamente incluídos no projeto argonavis.com.br Integra-se bem com o AntFarm Em geral, cada projeto deve ter um build.xml 20 Debugging e Testes argonavis.com.br JSwat é um debugger. Através dele pode-se marcar pontos de interrupção, obter diagnósticos e navegar através da execução de uma aplicação Através do plug-in Template pode-se gerar código para TestCases do JUnit O JUnit pode ser executado dentro do JEdit a partir da sua integração com o Ant 21 Ajuda de contexto argonavis.com.br CodeAid e DotComplete auxiliam o desenvolvedor com informações sobre métodos e atributos que podem ser usados em um contexto Ao se digitar um "." após uma variável, uma lista com os métodos e atributos disponíveis é exibida 22 Plug-in XML O plug-in de XML garante que o XML digitado seja bem formado argonavis.com.br XMLs mal formados têm os erros indicados no texto e no Console/ErrorList XML também pode validar XML se um esquema (DTD ou XML Schema) estiver associado com ele Usando um esquema, o JEdit oferece ajuda de contexto (mostrando quais tags podem ser usados no contexto e que atributos podem ser usados) Este DTD define as regras usadas pelo plug-in 23 Formatação de código JavaStyle, Jalopy e vários outros plug-ins reformatam código Java de acordo com um estilo pré-definido argonavis.com.br Endentação automática Posição das chaves (depois dos métodos ou linha seguinte) Comentários Javadoc gerados Outras opções configuráveis O código precisa estar bem formado XML Indenter faz a mesma coisa com arquivos XML 24 JBrowse JBrowse permite acesso rápido a métodos de uma classe argonavis.com.br Indispensável em classes grandes! Para configurar (Global Options), marque pelo menos a opção "Automatic Parse" para que a lista seja atualizada sempre que uma nova classe estiver na janela principal 25 Ant Farm AntFarm oferece uma interface para a execução de alvos de um build.xml através do Ant Cada alvo aparece como uma opção de menu argonavis.com.br Com o AntFarm, o JEdit alcança um nível de integração comparável aos IDEs comerciais: Selecionando-se uma opção de menu, pode-se Montar toda a aplicação (compilar, integrar) Executar a aplicação (produção ou debug) Gerar classes, documentos XML, etc. (templates) Rodar testes, benchmarks, validadores Gerar documentação (JavaDoc, executar templates, gerar relatórios HTML e PDF) Distribuir releases (criar JARs, WARs, EARS, deploy, ftp) Manter histórico local ou distribuído (CVS e similares) Executar e interagir com aplicações externas 26 Configuração do AntFarm O JEdit precisa saber a localização do script do Ant para executá-lo em uma JVM a parte Além disso, é útil ter algumas configurações default argonavis.com.br Localização do script do ant Para integração com o Project Viewer Gravar todos os buffers do JEdit antes de iniciar qualquer target 27 Extensão através do Ant Todas as tarefas baseadas na integração pelo Ant podem ser executadas sem o JEdit É o Ant que realiza tudo. O JEdit apenas oferece a interface e responde aos eventos do Ant É em torno do Ant, portanto, que deve ser feita a organização do projeto, como argonavis.com.br Estrutura de diretórios, nomes dos targets, etc. Rotinas de compilação, build, testes, execução, deploy Geração de código, documentação, etc. Projeto baseado no Ant pode ser montado em qualquer plataforma ou ambiente (IDE ou linha de comando) A seguir apresentaremos breve tutorial sobre Ant e como montar e gerenciar um ambiente de desenvolvimento 28 O que é Ant? Uma ferramenta para construção de aplicações Implementada em Java Baseada em roteiros XML Extensível (via scripts ou classes) 'padrão' do mercado Open Source (Grupo Apache, Projeto Jakarta) argonavis.com.br Semelhante a make, porém Mais simples e estruturada (XML) Mais adequada a tarefas comuns em projetos Java Independente de plataforma Onde encontrar: http://ant.apache.org 29 Para que serve? Para montar praticamente qualquer aplicação Java que consista de mais que meia dúzia de classes; Aplicações argonavis.com.br Distribuídas em pacotes Que requerem a definição de classpaths locais, e precisam vincular código a bibliotecas (JARs) Cuja criação/instalação depende de mais que uma simples chamada ao javac. Ex: RMI, CORBA, EJB, servlets, JSP,... Para automatizar processos frequentes Javadoc, XSLT, implantação de serviços Web e J2EE (deployment), CVS, criação de JARs, testes, FTP, email 30 Como funciona? Ant executa roteiros escritos em XML: 'buildfiles' Cada projeto do Ant possui um buildfile Subprojetos podem ter, opcionalmente, buildfiles adicionais chamados durante a execução do primeiro argonavis.com.br Cada projeto possui uma coleção de alvos Cada alvo consiste de uma seqüência de tarefas Exemplos de execução ant Procura build.xml no diretório atual e roda alvo default ant -buildfile outro.xml Executa alvo default de arquivo outro.xml ant compilar Roda alvo 'compilar' e possíveis dependências em build.xml 31 Como funciona (2) Ant <xml> <xml> <xml> <xml> build.xml <xdoclet> <xml> <xml> <xml> <xml> ejb-jar.xml build.xml *.java <ejb-jar> <javac> argonavis.com.br CVS <javadoc> <javac> subproj <ant> *.class <cvs> *.java *.class *.html <junit> Testes <jar update="true"> docs.zip ejb-jar.jar <copy> <mimemail> <ftp> deploy 32 Buildfile argonavis.com.br O buildfile é um arquivo XML: build.xml (default) Principais elementos <project default="alvo_default"> Elemento raiz (obrigatório): define o projeto. <target name="nome_do_alvo"> Coleção de tarefas a serem executadas em seqüência Pode-se estabelecer dependências entre alvos Deve haver pelo menos um <target> <property name="nome" value="valor"> Pares nome/valor usados em atributos dos elementos do build.xml da forma ${nome} Propriedades também podem ser definidas em linha de comando (-Dnome=valor) ou lidas de arquivos externos (atributo file) Tarefas (mais de 130) - usadas dentro dos alvos. <javac>, <jar>, <java>, <copy>, <mkdir>, ... 33 Buildfile (2) <?xml version="1.0" encoding="iso-8859-1" ?> <!-- Compila diversos arquivos .java --> Propriedades argonavis.com.br <project default="compile" basedir="."> <property name="src.dir" value="src" /> <property name="build.dir" value="classes" /> <target name="init"> <mkdir dir="${build.dir}" /> </target> Alvos <target name="clean"> <delete dir="${build.dir}" /> </target> <target name="compile" depends="init" description="Compila os arquivos-fonte"> <javac srcdir="${src.dir}" destdir="${build.dir}"> <classpath> Tarefas <pathelement location="${build.dir}" /> </classpath> </javac> Elementos embutidos nas tarefas </target> </project> 34 Exemplo Executando buildfile da página anterior C:\usr\palestra\antdemo> ant Buildfile: build.xml init: [mkdir] Created dir: C:\usr\palestra\antdemo\classes compile: [javac] Compiling 2 source files to C:\usr\palestra\antdemo\classes argonavis.com.br BUILD SUCCESSFUL Total time: 4 seconds C:\usr\palestra\antdemo> ant clean Buildfile: build.xml clean: [delete] Deleting dir: C:\usr\palestra\antdemo\classes BUILD SUCCESSFUL Total time: 2 seconds C:\usr\palestra\antdemo> ANTES de 'ant' DEPOIS de 'ant clean' build.xml src argonavis util Tiracentos.java TiracentosTest.java DEPOIS de 'ant' ou 'ant compile' build.xml src argonavis util Tiracentos.java TiracentosTest.java classes argonavis util Tiracentos.class TiracentosTest.class 35 Dependências Fazem com que a chamada de um alvo cause a chamada de outros alvos, em determinada ordem argonavis.com.br Promovem reuso de código <target <target <target <target <target <target <target <target <target init name="init" /> name="clean" /> name="compile" depends="init"/> name="javadoc" depends="compile"/> name="build" depends="compile"/> name="test" depends="build"/> name="deploy" depends="build"/> name="email" depends="archive"/> name="archive" depends="build, javadoc"/> <target name="re-deploy" depends="clean, deploy"/> compile javadoc build test deploy 1 archive 2 2 re-deploy 1 email clean 36 Tarefas condicionadas Algumas tarefas só são executadas dentro de determinadas condições <mkdir> só cria o diretório se este não existir <delete> só apaga o que existe (não faz nada se arquivo ou diretório não existir) <javac> compila apenas os arquivos *.java que foram modificados desde a última compilação argonavis.com.br Comportamento condicional do <javac> depende da estrutura de pacotes É preciso que a estrutura de diretórios dos fontes (diretório src/) reflita a estrutura de pacotes Ex: se Conta.java declara pertencer a pacote banco, deve estar em diretório banco dentro de src/ 37 O que se pode fazer com Ant? Compilar. <javac>, <csc> Gerar documentação <javadoc>, <junitreport>, <style>, <stylebook> Gerar código (XDoclet) <ejbdoclet>, <webdoclet> argonavis.com.br Executar programas <java>, <apply>, <exec> <ant>, <sql> Empacotar e comprimir <jar>, <zip>, <tar>, <war>, <ear>, <cab> Expandir, copiar, instalar <copy>, <delete>, <mkdir>, <unjar>, <unwar>, <unzip> Acesso remoto <ftp>, <telnet>, <cvs>, <mail>, <mimemail> Montar componentes <ejbc>, <ejb-jar>, <rmic> Testar unidades de código <junit> Executar roteiros e sons <script>, <sound> Criar novas tarefas <taskdef> 38 Tarefas úteis (1) <javac>: Chama o compilador Java <javac srcdir="dirfontes" destdir="dirbuild" > <classpath> <pathelement path="arquivo.jar" /> <pathelement path="/arquivos" /> </classpath> <classpath idref="extra" /> </javac> argonavis.com.br <jar>: Monta um JAR <jar destfile="bin/executavel.jar"> <manifest> <attribute name="Main-class" value="exemplo.main.Exec"> </manifest> <fileset dir="${build.dir}"/> </jar> 39 A tarefa <javac> É a tarefa mais importante de um processo típico de montagem Oferece uma fachada sobre compiladores Java Suporta outros compiladores (por exemplo, o IBM Jikes) Opções de linha de comando do compilador tornam-se atributos ou subelementos de <javac> javac -classpath abc.jar;c:\exemplos -d build *.java argonavis.com.br é o mesmo que <javac srcdir="." destdir="build"> <classpath path="abc.jar;c:\exemplos" /> </javac> 40 <javac> define FileSets O FileSet é um tipo de dados especial que representa uma árvore de arquivos e diretórios A tarefa <javac> é um tipo de FileSet argonavis.com.br Outra forma de escrever <javac> (usando path-like structures) para indicar o caminho de fontes (src) e classes (classpath) <javac destdir="${classes.dir}"> <src path="${gen.src.dir}"> <patternset refid="default.excludes" /> </src> <src path="${src.dir}" /> <classpath refid="${app.path}" /> </javac> 41 Tipos de dados (1) <fileset>: árvore de arquivos e diretórios argonavis.com.br Conteúdo do conjunto pode ser reduzido utilizando elementos <include> e <exclude> Usando dentro de tarefas que manipulam com arquivos e diretórios como <copy>, <zip>, etc. <copy todir="${build.dir}/META-INF"> <fileset dir="${xml.dir}" includes="ejb-jar.xml"/> <fileset dir="${xml.dir}/jboss"> <include name="*.xml" /> <exclude name="*-orig.xml" /> </fileset> </copy> Árvore a ser copiada para ${build.dir}/META-INF consiste de •O arquivo ejb-jar.xml localizado em ${xml.dir} •Todos os arquivos .xml de ${xml.dir}/jboss com exceção dos arquivos terminados em -orig.xml 42 Tarefas úteis (2) <mkdir>: cria diretórios <mkdir dir="diretorio" /> <copy>: copia arquivos <copy todir="dir" file="arquivo" /> <copy todir="dir"> <fileset dir="fonte" includes="*.txt" /> </copy> argonavis.com.br <delete>: apaga arquivos <delete file="arquivo" /> <delete dir="diretorio"/> 43 Tipos de dados (2) <patternset>: coleção de padrões de busca <patternset id="project.jars" > <include name="**/*.jar"/> <exclude name="**/*-test.jar"/> </patternset> Padrões podem ser reusados e são identificados pelo ID <path>: coleção de caminhos (path-like structures) argonavis.com.br Associa um ID a grupo de arquivos ou caminhos <path id="server.path"> <pathelement path="${j2ee.home}/lib/locale" /> <fileset dir="${j2ee.home}/lib"> <patternset refid="project.jars" /> </fileset> </path> <target name="compile" depends="init"> <javac destdir="${build.dir}" srcdir="${src.dir}"> <classpath refid="server.path" /> </javac> </target> 44 Tipos de dados (5): filtros <filter> e <filterset>: Permite a substituição de padrões em arquivos durante a execução de uma tarefa Caractere default: @ Exemplo: a cópia abaixo irá substituir todas as ocorrências de @javahome@ por c:\j2sdk1.4 nos arquivos copiados argonavis.com.br <copy todir="${dest.dir}"> <fileset dir="${src.dir}"/> <filterset> <filter token="javahome" value="c:\j2sdk1.4"/> </filterset> </copy> Pares token=valor podem ser carregados de arquivo: <filterset> <filtersfile file="build.properties" /> </filterset> Substituição sem tokens pode ser feita com <replacetoken> 45 Tarefas úteis (3) <javadoc>: Gera documentação do código-fonte. Exemplo: alvo generate-docs abaixo gera documentação excluindo classes que terminam em 'Test.java' argonavis.com.br <target name="generate-docs"> Copiar de ${src.dir} <mkdir dir="docs/api"/> <copy todir="tmp"> <fileset dir="${src.dir}"> <include name="**/*.java" /> <exclude name="**/*Test.java" /> </fileset> Procurar em todos os </copy> subdiretórios <javadoc destdir="docs/api" packagenames="argonavis.*" sourcepath="tmp" /> <delete dir="tmp" /> </target> Onde achar as fontes 46 Propriedades Todas podem ser lidas com ${nome} Nativas do Ant argonavis.com.br ant.file - caminho completo do build.xml ant.home - diretório de instalação do ant ant.java.version - versão do Java usado ant.project.name - nome do projeto ant.version - versão do Ant basedir - diretório onde está o build.xml Nativas do Java ou do JVM Qualquer propriedade nativa do Java pode ser lida da mesma forma 47 Como criar propriedades Podem ser definidas com <property> <property name="app.nome" value="jmovie" /> Podem ser carregadas de um arquivo <property file="c:/conf/arquivo.properties" /> app.ver=1.0 docs.dir=c:\\docs\\ codigo=15323 arquivo.properties argonavis.com.br Podem ser passadas na linha de comando c:\> ant -Dautor=Wilde Para recuperar o valor, usa-se ${nome} <jar destfile="${app.nome}-${app.ver}.jar"/> <echo message="O autor é ${autor}" /> <mkdir dir="build${codigo}" /> 48 Propriedades especiais <tstamp>: Grava um instante A hora e data podem ser recuperados como propriedades ${TSTAMP} ${DSTAMP} ${TODAY} hhmm aaaammdd dia mes ano 1345 20020525 25 May 2002 Novas propriedades podem ser definidas, locale, etc. Uso típico: <tstamp/> argonavis.com.br <property environment="env">: Propriedade de onde se pode ler variáveis de ambiente do sistema Dependende de plataforma <target name="init"> <property environment="env"/> <property name="j2ee.home" value="env.J2EE_HOME" /> </target> 49 Propriedades que apontam para caminhos Se uma propriedade representa um caminho no sistema de arquivos, ela pode ser definida com name/value, mas o valor será sempre um caminho relativo Usando name/location pode-se definir valores absolutos argonavis.com.br <property name="build.dir" location="classes" /> guardará o caminho completo ao diretório local build 50 Propriedades condicionais <available> irá definir uma propriedade (com valor true) se um determinado recurso existir <available property="arquivo.existe" file="importante.txt" type="file" /> argonavis.com.br A existência ou não de uma propriedade pode ser usada em blocos condicionais <target name="nome" if="arquivo.existe"> ... </target> 51 Propriedades condicionais <uptodate> seta uma propriedade se os arquivos de uma fonte estiverem em dia com os arquivos de um destino, identificado por um <mapper> A propriedade pode ser usada para realizar controle condicional argonavis.com.br Exemplo de uso <uptodate property="tests.unnecessary"> <srcfiles dir="src" includes="**/*.java" /> <mapper type="glob" from="*.java" to="*.class" /> </uptodate> 52 <input> Permite feedback do usuario em tempo real <input message="Continua (s/n)?" validargs="s,n" addproperty="continua" /> argonavis.com.br <condition property="abortar"> <equals arg1="n" arg2="${continua}"/> </condition> <fail if="abortar"> Processo encerrado pelo usuario. </fail> 53 Tarefas úteis (4): J2EE <ear destfile="app.ear" appxml="application.xml"> <fileset dir="${build}" includes="*.jar,*.war"/> </ear> argonavis.com.br <ejbjar srcdir="${build}" descriptordir="${xml.dir}" ... > <jboss destdir="${deployjars.dir}" /> </ejbjar> Há suporte aos principais servidores de aplicação <war destfile="bookstore.war" webxml="meta/metainf.xml"> <fileset dir="${build}/${bookstore2}" > <include name="*.jsp" /> WEB-INF/web.xml <exclude name="*.txt" /> Fileset para raiz do WAR </fileset> <classes dir="${build}" > Fileset para <include name="database/*.class" /> WEB-INF/classes </classes> Fileset para <lib dir="bibliotecas" /> WEB-INF/lib <webinf dir="etc" /> </war> Fileset para WEB-INF/ 54 Tarefas úteis (5): extensão <ejbdoclet> e <webdoclet>*: Geram código argonavis.com.br Requer JAR de xdoclet.sourceforge.net Ideal para geração automática de arquivos de configuração (web.xml, ejb-jar.xml, application.xml, taglibs, strutsconfig, etc.) e código-fonte (beans, value-objects) <ejbdoclet sourcepath="src" destdir="${build.dir}" classpathref="xdoclet.path" ejbspec="2.0"> <fileset dir="src"> <include name="**/*Bean.java" /> </fileset> <remoteinterface/> Detalhes da configuração do <homeinterface/> componente estão nos comentários de <utilobject/> JavaDocs do código-fonte dos arquivos <entitypk/> envolvidos e arquivos de template <entitycmp/> <deploymentdescriptor destdir="${dd.dir}"/> <jboss datasource="java:/OracleDS" /> </ejbdoclet> * Nomes convencionais criados a partir de tarefa externa 55 Tarefas úteis (6): execução <java>: executa o interpretador Java <target name="runrmiclient"> <java classname="hello.rmi.HelloClient" fork="true"> <jvmarg value="-Djava.security.policy=rmi.policy"/> <arg name="host" value="${remote.host}" /> <classpath refid="app.path" /> </java> </target> argonavis.com.br <exec>: executa um comando do sistema <target name="orbd"> <exec executable="${java.home}\bin\orbd"> <arg line="-ORBInitialHost ${nameserver.host}"/> </exec> </target> <apply>: semelhante a <exec> mas usado em executáveis que operam sobre outros arquivos 56 Tarefas úteis (7): rede <ftp>: Realiza a comunicação com um servidor FTP remoto para upload ou download de arquivos argonavis.com.br Tarefa opcional que requer NetComponents.jar (http://www.savarese.org) <target name="remote.jboss.deploy" depends="dist"> <ftp server="${ftp.host}" port="${ftp.port}" remotedir="/jboss/server/default/deploy" userid="admin" password="jboss" depends="yes" binary="yes"> <fileset dir="${basedir}"> <include name="*.war"/> <include name="*.ear"/> <include name="*.jar"/> </fileset> </ftp> </target> 57 Tarefas úteis (8): XSLT <style>: Transforma documentos XML em outros formatos usando folha de estilos XSLT (nativa) Usa TrAX (default), Xalan ou outro transformador XSL <style basedir="xmldocs" destdir="htmldocs" style="xmltohtml.xsl" /> argonavis.com.br Elemento <param> passa valores para elementos <xsl:param> da folha de estilos <style in="cartao.xml" out="cartao.html" style="cartao2html.xsl"> <param name="docsdir" expression="/cartoes"/> </style> (...) <xsl:param name="docsdir"/> build.xml (...) <xsl:valueof select="$docsdir"/> cartao2html.xsl (...) 58 Tarefas úteis (9): JDBC <sql>: Comunica-se com banco de dados através de um driver JDBC <property name="jdbc.url" value="jdbc:cloudscape:rmi://server:1099/Cloud " /> argonavis.com.br <target name="populate.table"> <sql driver="COM.cloudscape.core.RmiJdbcDriver" url="${jdbc.url}" userid="helder" password="helder" onerror="continue"> <transaction src="droptable.sql" /> <transaction src="create.sql" /> <transaction src="populate.sql" /> <classpath refid="jdbc.driver.path" /> </sql> </target> 59 Tarefas úteis (10): chamadas <ant>: chama alvo de subprojeto (buildfile externo) <target name="run-sub"> <ant dir="subproj" /> </target> Chama alvo default de build.xml localizado no subdiretório subproj/ <target name="run-sub"> <ant dir="subproj" > <property name="versao" value="1.0" /> </ant> </target> argonavis.com.br <antcall>: chama alvo local <target name="fazer-isto"> <antcall target="fazer"> <param name="oque" value="isto" /> </antcall> </target> Define propriedade que será lida no outro build.xml <target name="fazer-aquilo"> <antcall target="fazer"> <param name="oque" value="aquilo" /> </antcall> </target> <target name="fazer" if="oque"> <tarefa atributo="${oque}" /> </target> Template! 60 Efeitos sonoros <sound>: define um par de arquivos de som para soar no sucesso ou falha de um projeto Tarefa opcional que requer Java Media Framework Exemplo: argonavis.com.br No exemplo abaixo, o som festa.wav será tocado quando o build terminar sem erros fatais. vaia.wav tocará se houver algum erro que interrompa o processo: <target name="init"> <sound> <success source="C:/Media/festa.wav"/> <fail source="C:/Media/vaia.wav"/> </sound> </target> 61 Extensão usando XML Como o buildfile é um arquivo XML, pode-se incluir trechos de XML externos através do uso de entidades externas argonavis.com.br sound.xml <property <property file="sound.properties" file="sound.properties" /> /> <sound> <sound> <success <success source="${success.sound}"/> source="${success.sound}"/> <fail source="${fail.sound}"/> <fail source="${fail.sound}"/> </sound> </sound> <?xml <?xml version="1.0" version="1.0" encoding="iso-8859-1" encoding="iso-8859-1" ?> ?> <!DOCTYPE project [ <!DOCTYPE project [ <!ENTITY <!ENTITY sound sound SYSTEM SYSTEM "sound.xml"> "sound.xml"> ]> ]> <project <project default="dtd"> default="dtd"> <description>Gera <description>Gera um um DTD DTD para para oo Ant</description> Ant</description> <target name="init"> <target name="init"> &sound; &sound; </target> </target> <target <target name="dtd" name="dtd" depends="init"> depends="init"> <antstructure output="ant.dtd" <antstructure output="ant.dtd" /> /> </target> </target> </project> </project> 62 Ant + JUnit Ant: ferramenta para automatizar processos de construção de aplicações Java Pode-se executar todos os testes após a integração com um único comando: ant roda-testes argonavis.com.br Com as tarefas <junit> e <junitreport> é possível executar todos os testes gerar um relatório simples ou detalhado, em diversos formatos (XML, HTML, etc.) executar testes de integração São tarefas opcionais. É preciso ter no $ANT_HOME/lib optional.jar (distribuído com Ant) junit.jar (distribuído com JUnit) 63 Exemplo: <junit> argonavis.com.br <target name="test" depends="build"> <junit printsummary="true" dir="${build.dir}" fork="true"> <formatter type="plain" usefile="false" /> <classpath path="${build.dir}" / <test name="argonavis.dtd.AllTests" /> </junit> Formata os dados na tela (plain) </target> Roda apenas arquivo AllTests <target name="batchtest" depends="build" > <junit dir="${build.dir}" fork="true"> <formatter type="xml" usefile="true" /> <classpath path="${build.dir}" /> <batchtest todir="${test.report.dir}"> <fileset dir="${src.dir}"> <include name="**/*Test.java" /> <exclude name="**/AllTests.java" /> </fileset> </batchtest> Gera arquivo XML </junit> Inclui todos os arquivos que </target> terminam em Test.java 64 <junitreport> Gera um relatório detalhado (estilo JavaDoc) de todos os testes, sucessos, falhas, exceções, tempo, ... argonavis.com.br <target name="test-report" depends="batchtest" > <junitreport todir="${test.report.dir}"> <fileset dir="${test.report.dir}"> Usa arquivos XML <include name="TEST-*.xml" /> gerados por </fileset> <formatter> <report todir="${test.report.dir}/html" format="frames" /> </junitreport> </target> 65 Integração com outras aplicações Ant provoca vários eventos que podem ser capturados por outras aplicações Útil para implementar integração, enviar notificações por email, gravar logs, etc. Eventos argonavis.com.br Build iniciou/terminou Alvo iniciou/terminou Tarefa iniciou/terminou Mensagens logadas Vários listeners e loggers pré-definidos Pode-se usar ou estender classe existente. Para gravar processo (build) em XML: > ant -listener org.apache.tools.ant.XmlLogger 66 Integração com editores e IDEs Produtos que integram com Ant e oferecem interface gráfica e eventos para buildfiles: Antidote: GUI para Ant (do projeto Jakarta) http://cvs.apache.org/viewcvs/jakarta-ant-antidote/ JBuilder (AntRunner plug-in) http://www.dieter-bogdoll.de/java/AntRunner/ NetBeans e Forté for Java http://ant.netbeans.org/ Eclipse argonavis.com.br http://eclipse.org JEdit (AntFarm plug-in) http://www.jedit.org Jext (AntWork plug-in) ftp://jext.sourceforge.net/pub/jext/plugins/AntWork.zip 67 Integração com o JEdit Tela do AntFarm mostra alvos do Ant. Pode-se clicar sobre o alvo para executá-lo argonavis.com.br Resultados são mostrados no Console do JEdit 68 Como gerenciar projetos com o Ant Crie um diretório para armazenar seu projeto. Guarde na sua raiz o seu build.xml Use um arquivo build.properties para definir propriedades exclusivas do seu projeto (assim você consegue reutilizar o mesmo build.xml em outros projetos). Importe-o com <property file="build.properties" /> argonavis.com.br Dentro desse diretório, crie alguns subdiretórios src/ lib/ doc/ etc/ web/ Para armazenar o código-fonte Opcional. Para guardar os JARs de APIs usadas Opcional. Para guardar a documentação gerada Opcional. Para arquivos de configuração se houver Em projetos Web, para raiz de documentos do site O seu Ant script deve ainda criar durante a execução build/ dist/ Ou classes/. Onde estará o código compilado Ou jars/ ou release/. Onde estarão JARs criados 69 Alvos básicos do build.xml Você também deve padronizar os nomes dos alvos dos seus build.xml. Alguns alvos típicos são init clean compile build run test deploy Para criar dietórios, inicializar o ambiente, etc. Para fazer a faxina, remover diretórios gerados, etc. Para compilar Para construir a aplicação, integrar, criar JARs Para executar um cliente da aplicação Para executar os testes da aplicação Para implantar componentes Web e EJB argonavis.com.br Você pode usar outros nomes, mas mantenha um padrão 70 Exemplo de projeto argonavis.com.br <project default="compile" name="MiniEd"> <property file="build.properties"/> <target name="init"> <mkdir dir="${build.dir}"/> <mkdir dir="${dist.dir}"/> </target> <target name="clean"> ... </target> <target name="compile" depends="init"> ... </target> <target name="build" depends="compile">...</target> <target name="javadoc" depends="build"> ... </target> <target name="run" depends="build"> ... </target> </project> # Nome da aplicação app.name=minied # Nomes dos diretórios src.dir=src docs.dir=docs build.dir=classes dist.dir=jars # Nome da classe executável app.main.class=com.javamagazine.minied.MiniEditor root.package=com build.xml Estrutura dos arquivos (antes de executar o Ant) build.properties 71 Buildfile: aplicação gráfica executável <project default="compile" name="MiniEd"> <property file="build.properties"/> argonavis.com.br <target name="compile" depends="init"> <javac destdir="classes" srcdir="src"> <classpath> <pathelement location="classes"/> </classpath> </javac> </target> Definindo o JAR com atributo Main-class para torná-lo executável <target name="build" depends="compile"> <jar destfile="release/${app.name}.jar"> <manifest> <attribute name="Main-class" value="${app.main.class}" /> </manifest> <fileset dir="classes"/> </jar> </target> <target name="run" depends="build"> <java jar="release/${app.name}.jar" fork="true" /> </target> </project> # Nome da aplicação – este nome será usado para criar o JAR app.name=minied # Nome da classe executável app.main.class=com.javamagazine.minied.MiniEditor 72 argonavis.com.br Buildfile: aplicação RMI-IIOP <project name="Aplicação RMI" default="compile"> <target name="compile" depends="init"> <!-- Vários <target> omitidos --> <javac destdir="classes" srcdir="src" > <classpath refid="app.path" /> </javac> </target> <target name="buildrmi" depends="compile"> <rmic idl="true" iiop="true" base="classes"> <include name="**/rmiop/**Impl.class" /> <include name="**/portable/**Impl.class" /> </rmic> </target> <target name="runserver" depends="buildrmi"> <java classname="hello.rmiop.HelloServer" fork="true"> <jvmarg value="-Djava.rmi.server.codebase=${codebase}"/> <jvmarg value="-Djava.security.policy=${lib.dir}/rmi.policy"/> <jvmarg value="-Djava.naming.factory.initial=..."/> <jvmarg value="-Djava.naming.provider.url=iiop://${host}:1900"/> <classpath refid="app.path" /> </java> </target> <target name="orbd"> <exec executable="${java.home}\bin\orbd"> <arg line="-ORBInitialPort 1900 -ORBInitialHost ${host}"/> </exec> </target> </project> 73 Buildfile: aplicação Web build.xml <project default="deploy" name="Aplicação Web"> <property file="build.properties" /> <!-- init e clean omitidos --> <target name="compile" depends="init"> <javac srcdir="src" destdir="classes"> <classpath path="${servlet.jar}" /> </javac> </target> argonavis.com.br <target name="war" depends="compile"> <war warfile="release/${context}.war" webxml="etc/web.xml"> <fileset dir="web" /> <classes dir="classes" /> </war> </target> <target name="deploy" depends="war"> <copy todir="${deploy.dir}"> <fileset dir="release"> <include name="*.war" /> </fileset> # Localizacao do Servidor </copy> tomcat.home=/tomcat-4.0 </target> </project> build.properties # Altere para informar dir de instalacao deploy.dir=${tomcat.home}/webapps # Coloque aqui nome do contexto context=forum # JAR com Servlet API servlet.jar=${tomcat.home}/common/lib/servlet.jar 74 Buildfile: aplicação EJB build.xml <project name="Aplicação EJB" default="deploy"> <property file="build.properties" /> <!-- elementos <path> e <target> init, compile, clean omitidos --> <target name="build" depends="compile"> <copy todir="classes/META-INF"> <fileset dir="etc" includes="ejb-jar.xml"/> </copy> <jar jarfile="release/${app.name}.jar"> <fileset dir="classes" /> </jar> </target> argonavis.com.br <target name="deploy" depends="build"> <copy todir="${deploy.dir}" file="release/${app.name}.jar" /> </target> <target name="undeploy" depends="build"> <delete file="${deploy.dir}/${app.name}.jar" /> </target> </project> # Localizacao do Servidor jboss.home=/jboss-3.0.0 build.properties # Altere para informar dir de instalacao deploy.dir=${jboss.home}/server/default/deploy # Coloque aqui nome da aplicação app.name=forumejb 75 Buildfile: transformação XSL <project name="foptask-example" default="pdf"> <target name="setup" depends="check"> <taskdef name="fop" classname="argonavis.pdf.FopTask"> <classpath> ... </classpath> Mescla vários XML em um único </taskdef> </target> XML maior e converte em XSL-FO <target name="many2fo" depends="init"> <style in="template.xml" out="all.xml" style="many2one.xsl"> <param name="docsdir" expression="dados"/> </style> <style in="all.xml" out="all.fo" extension=".fo" style="many2fo.xsl"/> </target> argonavis.com.br Converte XSL-FO em PDF <target name="many2pdf" depends="many2fo"> <fop in="all.fo" out="all.pdf" /> </target> Converte vários XML em HTML <target name="html" depends="init"> <style basedir="dados" destdir="html" extension=".html" style="toHtml.xsl" /> </target> </project> 76 Ant programável Há duas formas de estender o Ant com novas funções Implementar roteiros usando JavaScript Criar novas tarefas reutilizáveis A tarefa <script> permite embutir JavaScript em um buildfile. Pode-se argonavis.com.br Realizar operações aritméticas e booleanas Utilizar estruturas como if/else, for, foreach e while Manipular com os elementos do buildfile usando DOM A tarefa <taskdef> permite definir novas tarefas Tarefa deve ser implementada em Java e estender Task Método execute() contém código de ação da tarefa Cada atributo corresponde a um método setXXX() 77 Exemplo de script Cria 10 diretórios pasta1, pasta2, etc. em pastas/ <project name="scriptdemo" default="makedirs" > argonavis.com.br <property name="result.dir" value="pastas" /> Obtém referência para objeto <target name="setup-makedirs"> que implementa tarefa mkdir <mkdir dir="${result.dir}" /> <script language="javascript"><![CDATA[ for (i = 0; i < 10; i++) { criadir = scriptdemo.createTask("mkdir"); // Obter propriedade ${result.dir} deste projeto root = scriptdemo.getProperty("result.dir"); // Definir diretorio a criar criadir.setDir(new Packages.java.io.File(root+"/pasta"+(i+1))); // Executa tarefa mkdir (todo Task tem um metodo execute) criadir.execute(); } ]]></script> </target> <target name="makedirs" depends="setup-makedirs" /> </project> 78 Exemplo de definição de tarefas (1) import org.apache.tools.ant.*; public class ChangeCaseTask extends Task { argonavis.com.br public static final int UPPERCASE = 1; private String message; private int strCase = 0; } <target name="define-task" depends="init"> <taskdef name="changecase" classname="ChangeCaseTask"> <classpath> <pathelement location="tasks.jar" /> </classpath> </taskdef> </target> <target name="run-task" depends="define-task"> <changecase message="Mensagem simples" /> <changecase message="Mensagem em caixa-alta" case="uppercase" /> <changecase message="Mensagem em caixa-baixa" case="lowercase" /> </target> public void execute() { log( getMessage() ); } public void setMessage(String message) { this.message = message; } public void setCase(String strCase) { if (strCase.toLowerCase().equals("uppercase")) this.strCase = UPPERCASE; else if (strCase.toLowerCase().equals("lowercase")) this.strCase = -UPPERCASE; } public String getMessage() { switch(strCase) { case UPPERCASE: return message.toUpperCase(); case -UPPERCASE: return message.toLowerCase(); default: return message; } } Trecho do build.xml usando tarefa <changecase> Cada atributo é definido em um método setAtributo(String) Método execute() chama log(), que imprime resultado na saída do Ant (Exceções foram ignoradas por falta de espaço) 79 Conclusões Ant é uma ferramenta indispensável em qualquer projeto de desenvolvimento Java Permite automatizar todo o desenvolvimento Facilita a montagem da aplicação por outras pessoas Ajuda em diversas tarefas essenciais do desenvolvimento como compilar, rodar, testar, gerar JavaDocs, etc. Independe de um IDE comercial (mas pode ser facilmente integrado a um) argonavis.com.br Use o Ant em todos os seus projetos Crie sempre um projeto e um buildfile, por mais simples que seja a sua aplicação Escreva buildfiles que possam ser reutilizados Desenvolva o hábito de sempre usar o Ant 80 Fontes [1] Richard Hightower e Nicholas Lesiecki. Java Tools for eXtreme Programming. Wiley, 2002. Explora Ant e outras ferramentas em ambiente XP. [3] Apache Ant User's Manual. Ó tima documentação repleta de exemplos. [3] Steve Lougran. Ant In Anger - Using Ant in a Production Development System. (Ant docs) Ó timo artigo com boas dicas para organizar um projeto mantido com Ant. [4] Martin Fowler, Matthew Foemmel. Continuous Integration. http://www.martinfowler.com/articles/continuousIntegration.html. Ó timo artigo sobre integração contínua e o CruiseControl. Hatcher. Java Development with Ant. Manning Publications. August 2002. Explora os recursos básicos e avançados do Ant, sua integração com JUnit e uso com argonavis.com.br [5] Erik ferramentas de integração contínua como AntHill e CruiseControl. [6] Jesse Tilly e Erik Burke. Ant: The Definitive Guide. O'Reilly and Associates. May 2002. Contém referência completa e ótimo tutorial sobre recursos avançados como controle dos eventos do Ant e criação de novas tarefas. [7] Karl Fogel. Open Source Development with CVS. Coriolis Press. http://cvsbook.red-bean.com/. 81 Baseado no Curso J820 Produtividade e Qualidade em Java: Ferramentas e Metodologias Revisão 1.1 e artigo publicado na Java Magazine, no. 3 © 2002, 2003, Helder da Rocha ([email protected]) argonavis.com.br