Hey! Saia do armário e brinque com Ant script você também

Boa noite a todos,

Para tirar um pouco da poeira aqui do blog vou postar algo um pouco diferente e que até não sou muito habituado mas estou gostando de mexer, o famoso Ant script.

Sobre o Ant

O Ant é uma biblioteca escrita puramente em Java e pode ser incorporada em todos os projetos Java, usualmente estamos acostumados a usar ele diretamente pelo Eclipse (assim como o JUnit) porque o Eclipse dá um suporte nativo ao Ant além de algumas matoragens como sintax hightlight e validação.

Mas pra que usarmos ele? Bom um dos usos mais comuns dele é para a compilação de código, mas também nos dá suporte a inúmeras outras coisas como cópiar, testar, executar, etc. A Apache Foundation define o Ant como um script de construção, por isso talvez o seu nome de “formiga” ou “formiginha”.

Emprego

Como falei a pouco, podemos usar ele para inúmeras coisas, geralmente usamos ele para compilar algum código como por exemplo um projeto WEB do Eclipse, vamos imaginar um cenário aqui pessoal:

Estamos codificando uma aplicação Web Java pelo Eclipse, e ela já está madura em que atualmente apenas modificamos ou personalizamos algumas de suas funcionalidades. Logo as bibliotecas utilizadas pelo projeto não necessitam mais serem enviadas para o servidor a cada nova atualização. Mas quando empacotamos no Eclipse todos estes jars vão junto para o arquivo WAR, daí eu tenho que abrir o arquivo e remover todos os jars de dentro dele toda vez…

Pronto pessoal! temos um cenário agora…abaixo tem um exemplo de como criamos o arquivo WAR (Web application ARchive) pelo Eclipse.

Mãos a massa

Vamos agora criar um Ant script dentro do nosso projeto (lembrando que  também poderia ser em um projeto utilitário só para os Ant scripts dos projetos envolvidos). O script nada mais é do que um arquivo XML só que com as tags da biblioteca Ant. Vamos agora fazer o mesmo procedimento que o Eclipse nos fornece só que via Ant. Abaixo temos a abertura do nosso arquivo Ant:

No Eclipse temos uma view específica para colocarmos os nossos scripts, para habilitá-la siga a ilustração da figura abaixo:

Depois de selecionada, uma view (aba) será carregada e você poderá arrastar os seus arquivos .xml para lá para executá-los. Embora isso não seja necessário mas ajuda bastante para deixar a workspace organizada. Eu deixo por exemplo assim:

 

Voltando ao nosso arquivo, se selecionarmos ele e clicarmos no botão “Run“, ele deverá mostrar algo parecido com isso:

Buildfile: D:appeclipseworkspacecontrole-propriedadeant-deploy.xml

depends:
default:
[echo] Início do deploy
BUILD SUCCESSFUL
Total time: 590 milliseconds

Ele executou perfeitamente, mas não tem nenhuma funcionalidade útil para o nosso projeto. Então vamos começar a deixar o nosso exemplo mais interessante. O projeto que eu estou usando para o nosso artigo é um projeto com o VRaptor 3, e nós vamos empacotar ele em um arquivo WAR sem os jars conforme o descrito no nosso cenário anteriormente.

Vamos declarar uma variável dentro do nosso arquivo para definirmos o diretório onde irá ficar o arquivo WAR, neste caso será dentro do projeto mesmo, desta forma declaramos da seguinte forma:

[xml]
<property name=”diretorio.do.deploy” value=”deploys”/>
[/xml]

 A pasta “deploys” é uma pasta que está na raiz do meu projeto, logo “controle-propriedades/deploys”, assim o caminho que estou informando é relativo, fica mais flexível e você ainda pode ir acessando outros locais fora deste projeto sem problema algum.

Agora dentro da tag “target” iremos usar uma tag marota para fazer compilação e empacotamento, a tag sugestiva chamada “<war>“. Essa tag recebe como parâmetro obrigatório qual é o arquivo de destino, assim vamos informar o local:

[xml]
<target name=”default”>
<war destfile=”${diretorio.do.deploy}/controle-propriedades.war”>
</war>
</target>
[/xml]

Se executarmos o nosso arquivo ele irá gerar uma saída semelhante a apresentada abaixo:

Buildfile: D:appeclipseworkspacecontrole-propriedadeant-deploy.xml
default:
[echo] Início do deploy
[war] Building MANIFEST-only jar: D:appeclipseworkspacecontrole-propriedadedeployscontrole-propriedades.war

BUILD FAILED
D:appeclipseworkspacecontrole-propriedadeant-deploy.xml:11: No WEB-INF/web.xml file was added.
If this is your intent, set needxmlfile=’false’

Total time: 600 milliseconds

Isso acontece porque não configuramos corretamente a tag, nesse caso teríamos que dizer que não há arquivo descritor XML para validação, então vamos adicionar um parâmetro que informa qual é o nosso arquivo descritor do projeto, o web.xml, fazemos isso da seguinte forma:

[xml]
<target name=”default”>
<war destfile=”${diretorio.do.deploy}/controle-propriedades.war” webxml=”WebContent/WEB-INF/web.xml”>
</war>
</target>
[/xml]

Agora se executarmos o nosso script já temos um arquivo WAR com a estrutura básica do projeto Web. A figura abaixo ilustra isso:

 Se formos olhar a pasta WEB-INF dentro nosso arquivo WAR iremos ver que não há nenhuma classe compilada, assim precisamos dizer ao nosso script para fazer isso, assim fazemos o seguinte:

[xml]
<target name=”default”>
<war destfile=”${diretorio.do.deploy}/controle-propriedades.war” webxml=”WebContent/WEB-INF/web.xml”>
<classes dir=”WebContent/WEB-INF/classes”/>
</war>
</target>
[/xml]

Executando o script agora, podemos ver que todas as classes e resources do nosso projeto foram compilados e adicionados dentro do arquivo WAR conforme o ilustrado na figura abaixo:

Bom, o nosso arquivo agora está quase pronto, mas ainda falta uma coisa que é muito importante…os nossos arquivos JSPs, JS, HTML, etc que ficam no diretório público do projeto. Para isto teremos que combinar o uso de outra tag marota do Ant, a <fileset>. Essa tag nos permite manipular os arquivos que desejamos trazer ao processo de empacotamento do WAR file (também pode ser usado para outros fins). Assim incrementamos mais um pouco o nosso script:

[xml]
<target name=”default”>
<war destfile=”${diretorio.do.deploy}/controle-propriedades.war” webxml=”WebContent/WEB-INF/web.xml”>
<classes dir=”WebContent/WEB-INF/classes”/>
<fileset dir=”WebContent”/>
</war>
</target>
[/xml]

Agora se executarmos iremos ficar com todos os arquivos que estavam dentro do nosso diretório “WebContent“. Maravilha! podemos jogar esse arquivo lá dentro do diretório “webapps” do Tomcat e ele irá descompactar automaticamente para a gente :), só que esse não foi o combinado, ainda temos os jars dentro do arquivo WAR conforme a imagem abaixo:

O uso da tag marota <fileset> nos permite criar regras para os arquivos que não quisermos, assim podemos fazer sem nenhum esforço grande uma regrinha para não adicionar nenhum arquivo .jar dentro do WAR final. A tag que iremos usar dentro da <fileset> é a <exclude> e dizemos que não queremos nenhum arquivo que termine com .jar.

[xml]
<target name=”default”>
<war destfile=”${diretorio.do.deploy}/controle-propriedades.war” webxml=”WebContent/WEB-INF/web.xml”>
<classes dir=”WebContent/WEB-INF/classes”/>
<fileset dir=”WebContent”>
<exclude name=”WEB-INF/lib/*.jar”/>
</fileset>
</war>
</target>
[/xml]

Agora se olharmos o arquivo WAR gerado depois da execução iremos ver que nenhum arquivo .jar foi enviado:

Pronto! :)

Conclusão

Para quem está habituado a utilização de linha de comando, o uso do Ant script pode ser bem familiar. O seu uso vai muito mais além do que apenas este exemplo do post aqui, onde estou trabalhando atualmente usamos o Ant para compilar e preparar diversos projetos (tanto Web como Desktop) para o versionamento e releases. As possibilidades são praticamente infinitas, o emprego do Ant para lhe ajuda na economia de tempo de tarefas rotineiras e trabalhosas.

Ah, quase ia esquecendo de comentar, você ainda pode usar os recursos da biblioteca do Ant para codificar dentro das suas classes alguma task (ainda preciso estudar isso) e também pode executar os seus scripts usamos a mesma JRE da workspace do seu eclipse, e poder usar tasks pré-definidas do Eclipse IDE, como por exemplo para atualizar o projeto após a execução do mesmo.

[xml]
<target name=”default”>
<eclipse.refreshLocal resource=”controle-propriedades” depth=”infinite” />
</target>
[/xml]

Referências

Ant manual – http://ant.apache.org/manual/Types/fileset.html

WAR Task – http://ant.apache.org/manual/Tasks/war.html

Eclipse Ant tasks – http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/ant_eclipse_tasks.htm

Abraços e até a próxima.