Escolar Documentos
Profissional Documentos
Cultura Documentos
Downloads
Caso queira usar o IVY imediatamente a partir desse vídeo, pode baixar o projeto aqui. O
projeto deve ser importado no Eclipse.
Introdução ao IVY
ANT como ferramenta de construção de software ajuda muito na automatização de tarefas
comuns no build de software. Quando construímos uma aplicação também importa saber
componentes usaremos e suas versões. No mundo Java esses componentes são as
bibliotecas, ou seja, as dependências da aplicação. A aplicação só funciona com esses
componentes em uma versão específica. Isso significa que o desenvolvedor precisa se
preocupar com as dependências.
O IVY é uma ferramenta que ajuda no gerenciamento das dependências e seu uso com
ANT é muito simples. Para um projeto que já utiliza ANT como ferramenta de build o IVY
pode ser facilmente integrado. Vamos configurar ANT com IVY e usar tarefas no ANT para
resolver as dependências do projeto.
Com IVY podemos usar uma tarefa no ANT que automatiza esses passos. Isso deve ser
tão fácil de usar quanto compilar ou empacotar o projeto, ou seja, apenas uma chamada
no IDE ou na linha de comando. O IVY deve verificar e atualizar as dependências do
projeto e avisar quando há conflitos entre JARs.
Encontrando as dependências
Para o primeiro exemplo, vamos definir as dependências de uma aplicação web que
pretende usar Spring MVC como controlador MVC. Como já foi dito, o IVY baixará as
dependências automaticamente, mas de onde ele as baixará?
Existem servidores na internet com a tarefa de fornecer JARs para aplicações. Esses
servidores, ou melhor repositórios, foram criados para serem utilizados com outra
ferramenta de construção de software, o Maven. O IVY utiliza os mesmos repositórios do
Maven, aproveitando a ampla infraestrutura já existente.
Existem vários repositórios na internet. Um lugar central para pesquisar pelos artefatos é o
site http://mvnrepository.com.
<dependencies>
<dependency org="org.springframework" name="spring-webmvc"
rev="3.1.0.RELEASE" conf="default" />
</dependencies>
</ivy-module>
Para o ANT achar a tarefa é preciso ter o JAR do IVY no classpath. O JAR vem da
distribuição do Apache IVY e pode ser baixado no site do projeto: http://ant.apache.org/ivy/
Então podemos disponibilizar o JAR do IVY (por exemplo ivy-2.2.0.jar) no classpath do
ANT. No final é o ANT que vai usar IVY. Para adicionar o IVY no classpath podemos
configurar o classpath pelo comando ant com o argumento -lib, por exemplo:
Alternativamente podemos declarar uma tag path com a biblioteca do IVY e definir na task
no build.xml. Essa maneira tem a vantagem de não precisarmos lembrar de passar o
JAR do IVY na linha de comando:
<path id="ivy.lib.path">
<fileset dir="ivy-lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
Pronto, a integração do ANT e IVY está feita. Foi preciso definir o classpath (JAR do IVY
na pasta lib), declarar o namespace e usar a tarefa do IVY (ivy:retrieve) dentro do
build.xml.
O arquivo iyy.xml deve estar na mesma pasta do build.xml. Assim podemos executar o
target ant atualiza-dependencias gerando o seguinte resultado:
atualiza-dependencias:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/usr/share/ant/lib/ivy-
2.2.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies ::
br.com.caelum#agenda;working@nico-vaio
[ivy:retrieve] confs: [default]
[ivy:retrieve] found org.springframework#spring-webmvc;3.1.0.RELEASE in
public
[ivy:retrieve] [3.1.0.RELEASE] org.springframework#spring-
webmvc;3.1.0.RELEASE
....
[ivy:retrieve] downloading
http://repo1.maven.org/maven2/org/springframework/spring-webmvc/3.1.0.RELEASE
/spring-webmvc-3.1.0.RELEASE.jar ...
[ivy:retrieve] ..............................................................
.............
....
Cache do Ivy
A segunda execução será muito mais rápido. Mas por quê? O que acontece é que o IVY
baixa os JARs do repositório, colocando-os dentro da pasta lib do projeto. Mas além de
colocar as bibliotecas na pasta lib o IVY guarda os JARs em uma pasta independente do
projeto. Normalmente essa pasta se encontra na raiz da pasta do usuário e se chama
.ivy2:
/pastaDoUsuario/.ivy/cache/....
- aopalliance.jar
- commons-logging.jar
- spring-asm.jar
- spring-aop.jar
- spring-beans.jar
- spring-context.jar
- spring-context-support.jar
- spring-core.jar
- spring-expression.jar
- spring-web.jar
- spring-webmvc.jar
Resumo
Vimos como integrar o IVY com ANT, usando a tarefa ivy:retrieve. Como o IVY
aproveita os mesmo repositório do Maven podemos procurar as dependências dentro
desses repositórios. Para a configuração das dependências usamos um arquivo especifico
do IVY, o ivy.xml.
Atividade 1 de 8
Como se chama o arquivo do Ivy para configurar as dependências?
17/12/2013 10:24
ivy.properties
ivy-deps.properties
deps.xml
ivy.properties.xml
ivy-properties.xml
ivy.xml
ivy-deps.xml
Atividade 2 de 8
Onde o Ivy procura as dependências por padrão?
17/12/2013 10:25
Atividade 3 de 8
Como configurar o ANT para usar as tarefas do Ivy?
17/12/2013 10:25
O JAR do Ivy deve estar dentro do classpath E o namespace do Ivy deve estar
definido.
Basta definir no classpath o JAR do Ivy.
Atividade 4 de 8
Como se chama a tarefa do Ivy para baixar e adicionar as dependências no projeto?
17/12/2013 10:25
restore
download
retrieve
define
Atividade 5 de 8
Como se chama a pasta que o Ivy usa para colocar as dependências no projeto?
17/12/2013 10:26
jars
lib
target
deps
Atividade 5 de 8
Como se chama a pasta que o Ivy usa para colocar as dependências no projeto?
17/12/2013 10:26
jars
lib
target
deps
Atividade 7 de 8
Acesse o http://mvnrepository.com. Procure pela dependências hibernate-core e escolhe
a versão 4.1.1.FINAL. Cole a declaração do Ivy aqui:
Atividade 8 de 8
A empresa DRLN (nome fictício, site fictício: http://drln.com.br) está desenvolvendo uma
aplicação web com Spring MVC na versão 3.1.0 para administrar tarefas dos funcionários.
O nome do projeto é drln-tarefas. Crie o ivy.xml e build.xml para carregar as
dependências.
Explicação
Nossa aplicação web agenda de exemplo foi estruturada da seguinte maneira: uma pasta
src com pacotes para controladores, modelo e outro para DAO's e uma pasta src-teste
com as nossas classes de testes.
Temos o arquivo ivy.xml com o elemento info e depedencies preparados, mas ainda
sem dependências concretas.
<dependencies>
</dependencies>
</ivy-module>
<path id="ivy.lib.path">
<fileset dir="ivy-lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
</project>
<dependencies>
<dependency org="org.springframework" name="spring-webmvc"
rev="3.1.0.RELEASE" />
<dependency org="mysql" name="mysql-connector-java" rev="5.1.18" />
<dependency org="jstl" name="jstl" rev="1.2" />
</dependencies>
</ivy-module>
Para cada dependência queremos que o IVY carregue apenas o JAR's (dependência e
dependências transitivas) e nenhuma dependência opcional, nem o javadoc ou código
fonte, por isso adicionaremos a configuração default para cada dependência.
<dependencies>
<dependency org="org.springframework" name="spring-webmvc"
rev="3.1.0.RELEASE" conf="default"/>
<dependency org="mysql" name="mysql-connector-java" rev="5.1.18"
conf="default"/>
<dependency org="jstl" name="jstl" rev="1.2" conf="default"/>
</dependencies>
atualiza-dependencias:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url =
jar:file:/Users/caelum/Documents/IVY/IVY-workspace/agenda/ivy-lib/ivy-
2.2.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies ::
br.com.caelum#agenda;working@MacBook-Pro-de-Caelum.local
[ivy:retrieve] confs: [default]
[ivy:retrieve] found org.springframework#spring-webmvc;3.1.0.RELEASE in
public
[ivy:retrieve] found org.springframework#spring-asm;3.1.0.RELEASE in
public
[ivy:retrieve] found org.springframework#spring-beans;3.1.0.RELEASE in
public
[ivy:retrieve] found org.springframework#spring-core;3.1.0.RELEASE in
public
[ivy:retrieve] found commons-logging#commons-logging;1.1.1 in public
[ivy:retrieve] found org.springframework#spring-context;3.1.0.RELEASE in
public
[ivy:retrieve] found org.springframework#spring-aop;3.1.0.RELEASE in
public
[ivy:retrieve] found aopalliance#aopalliance;1.0 in public
[ivy:retrieve] found org.springframework#spring-expression;3.1.0.RELEASE
in public
[ivy:retrieve] found org.springframework#spring-context-
support;3.1.0.RELEASE in public
[ivy:retrieve] found org.springframework#spring-web;3.1.0.RELEASE in
public
[ivy:retrieve] found mysql#mysql-connector-java;5.1.18 in public
[ivy:retrieve] found jstl#jstl;1.2 in public
[ivy:retrieve] :: resolution report :: resolve 730ms :: artifacts dl 12ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 13 | 0 | 0 | 0 || 13 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#agenda
[ivy:retrieve] confs: [default]
[ivy:retrieve] 13 artifacts copied, 0 already retrieved (4796kB/108ms)
No projeto, vimos que o IVY criou a pasta lib com os 13 JARs baixados, mas os mesmos
JARs já estavam na pasta WEB-INF/lib para que fosse possível compilar e rodar a
aplicação.
Portando temos mais um problema: os JAR's do junit. Quem deve resolver é o IVY, então
vamos procurar pelo junit no repositório do maven para pegar a versão mais nova:
Com a nova dependência vamos testar na linha de comando com ANT executando o
comando: ant atualiza-dependencias:
.....
[ivy:retrieve] found junit#junit;4.10 in public
[ivy:retrieve] found org.hamcrest#hamcrest-core#jstl;1.1 in public
....
[ivy:retrieve] :: resolution report :: resolve 731ms :: artifacts dl 17ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 15 | 0 | 0 | 0 || 15 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#agenda
[ivy:retrieve] confs: [default]
[ivy:retrieve] 15 artifacts copied, 13 already retrieved (322kB/46ms)
Carregou o junit, mas a biblioteca foi colocado pelo o IVY dentro da pasta WebContent. Os
JAR's do junit devem fazer parte da pasta WEB-INF/lib. Podemos então apagar esses
dois jars.
<dependencies>
<dependency org="junit" name="junit" rev="1.4" conf="teste->default" />
<dependency org="org.springframework" name="spring-mvc"
rev="3.1.0.RELEASE" conf="webapp->default" />
.....
</dependencies>
Assim a configuração teste foi mapeado (->) para default default para aquele
dependência, wepapp carregara tudo que é default.
Aplicando configurações no
build
Voltando ao nosso build.xml, na tag ivy:retrieve vamos aplicar as configurações
webapp e teste no para associar a tarefa com a configuração, ou seja no final com um
grupo de dependências.
Rodando mais uma vez na linha de comando o ANT: ant atualiza-dependencias vemos
que DOIS relatórios foram gerados: uma para a configuração webapp e outro para teste:
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| webap | 13 | 0 | 0 | 0 || 13 | 0 |
---------------------------------------------------------------------
.....
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| teste | 2 | 0 | 0 | 0 || 2 | 0 |
---------------------------------------------------------------------
Além dessas opções que definem a abrangência podemos querer carregar o código fonte
também (sources), ou a documentação javadoc. É possível realizar combinações, por
exemplo:
webapp->master, sources
webapp->compile, javadoc
teste->*
No exemplo acima, webapp foi mapeado para master e sources. Isso significa que
queremos carregar o jar principal apenas e o código fonte dessa dependência.
<ivy:retrieve pattern="/[config]/[type]/[artifiact]-[revision].[ext]"
conf="webapp" />
Nesse caso, o pattern é composto pelo config (ou seja webapp), o type (por exemplo jar
ou javadoc). artifact é o nome da dependência (spring-webmvc) e revision e a versão,
além da e a extensão do artifato (jar normalmente).
Atividade 1 de 5
Às vezes, para uma determinada dependência, queremos que o Ivy carregue apenas os
JARs e nenhuma dependência opcional. Para isso, podemos passar como parâmetro o
valor default em um determinado atributo do elemento dependency. Que atributo é esse?
17/12/2013 10:27
branch
conf
name
transitive
Atividade 1 de 5
Às vezes, para uma determinada dependência, queremos que o Ivy carregue apenas os
JARs e nenhuma dependência opcional. Para isso, podemos passar como parâmetro o
valor default em um determinado atributo do elemento dependency. Que atributo é esse?
17/12/2013 10:27
branch
conf
name
transitive
Atividade 3 de 5
Para organizarmos melhor nossa aplicação queremos separar as bibliotecas necessárias
para rodar a aplicação web das bibliotecas para executar os testes, ambos em
configurações diferentes.
Altere o ivy.xml para mapear essas dependências para que as bibliotecas do JUnit
fiquem defindas em teste->default e as bibliotecas do Spring fiquem em webapp-
>default:
Atividade 4 de 5
Criamos duas configurações webapp e teste no exercício anterior. Com este mapeamento
já feito queremos agora separar as bibliotecas em pastas diferentes.
Atividade 5 de 5
Na nossa aplicação já se encontra um ivy.xml. Nele declaramos uma configuração
runtime que foi mapeado para default. Com ela carregaremos o JAR principal do
Hibernate e todas as dependências transitivas.
Para esse exercício altere a configuração da dependência para carregar apenas o JAR
principal E o código fonte. Cole o XML da definição da dependência abaixo.
Explicação
<path id="ivy.lib.path">
<fileset dir="ivy-lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
Vamos copiar então essa dependência colando-a dentro do nosso ivy.xml. Só garantindo
através da configuração que apenas os JARs principais serão carregados, usando o
atributo conf="default":
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<dependencies>
<dependency org="org.hibernate" name="hibernate-annotations"
rev="3.5.6-Final" conf="default"/>
</dependencies>
</ivy-module>
atualiza-dependencias:
....
[ivy:retrieve] confs: [default]
[ivy:retrieve] found org.hibernate#hibernate-annotations;3.5.6-Final in
public
[ivy:retrieve] found org.hibernate#hibernate-core;3.5.6-Final in public
[ivy:retrieve] found antlr#antlr;2.7.6 in public
[ivy:retrieve] found commons-collections#commons-collections;3.1 in
public
[ivy:retrieve] found dom4j#dom4j;1.6.1 in public
[ivy:retrieve] found xml-apis#xml-apis;1.0.b2 in public
[ivy:retrieve] found javax.transaction#jta;1.1 in public
[ivy:retrieve] found org.slf4j#slf4j-api;1.5.8 in public
[ivy:retrieve] found org.hibernate#hibernate-commons-
annotations;3.2.0.Final in public
[ivy:retrieve] found org.hibernate.javax.persistence#hibernate-jpa-2.0-
api;1.0.0.Final in public
[ivy:retrieve] :: resolution report :: resolve 418ms :: artifacts dl 12ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 10 | 0 | 0 | 0 || 10 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#agenda
[ivy:retrieve] confs: [default]
[ivy:retrieve] 10 artifacts copied, 0 already retrieved (4461kB/18ms)
...
Desabilitando dependências
transitivas
O tag dependency do IVY possui elemento transitive que por padrão é true, mas
mudaremos para false para carregar apenas a dependência declarada, o hibernate-
annotation na versão 3.5.6.
atualiza-dependencias:
....
[ivy:retrieve] confs: [default]
[ivy:retrieve] found org.hibernate#hibernate-annotations;3.5.6-Final in
public
[ivy:retrieve] :: resolution report :: resolve 111ms :: artifacts dl 3ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 1 | 0 | 0 | 0 || 1 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#agenda
[ivy:retrieve] confs: [default]
[ivy:retrieve] 1 artifacts copied, 0 already retrieved (356kB/5ms)
Podemos ver que um módulo foi tirado (evicted). Um pouco mais para cima é mostrado
qual dependência não foi usada, nesse caso a commons-collections na versão 3.1.
Olhando por dentro da pasta lib, percebemos que o commons-collections na versão 3.2
foi o escolhido, ou seja a versão mais recente.
Gerenciador de conflitos
Exite um gerenciador (conflict manager) que decide quais são os JAR a utilizar, mas
podemos decidir qual gerenciador utilizar. O conflict manager padrão se chama lastest-
revision, ou seja como já vimos, usa a versão mais nova, e por isso foi utilizado o
commons-collections na versão 3.2 . O gerenciador é definido o no ivy.xml:
<conflicts>
<manager name="latest-revision" />
</conflicts>
Mas podemos definir um outro conflict manager, por exemplo, all. Vamos testar o conflict
manager all executando novamente ANT.
Dentro do ivy.xml:
<conflicts>
<manager name="all" />
</conflicts>
E também temos um conflict manager que se chama strict. Se algum conflito ocorrer,
nada é carregado e o build falha. No ivy.xml:
<conflicts>
<manager name="strict" />
</conflicts>
[ivy:retrieve] :: problems summary ::
[ivy:retrieve] :::: ERRORS
[ivy:retrieve] commons-collections#commons-collections;3.2 (needed by
[org.apache.myfaces.core#myfaces-impl;2.1.7]) conflicts with commons-
collections#commons-collections;3.1 (needed by [org.hibernate#hibernate-
core;3.5.6-Final])
[ivy:retrieve]
[ivy:retrieve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
BUILD FAILED
Criação do relatório de
dependências
Existe uma outra forma de visualizar as dependências. O Ivy vem uma tarefa já integrada
para gerar confortavelmente um relatório. Ela se chama ivy:report e recebe um atributo
que define o nome da pasta do relatório. Vamos gerar um relatório com Ivy na pasta
report:
<ivy:report todir="report"/>
Executando ANT novamente gerar então um relatório umas páginas html. Abrindo a
página html temos o status das dependências, os conflitos e um resumo de todas as
dependências. No nosso relatório temos duas dependências principais: o MyFaces e o
Hibernate-annotation e as dependências transitivas de cada um. Depois uma listagem de
cada dependência principal e transitiva.
Exclusão de dependências
Pode ainda, para cada dependência, solicitar a exclusão de alguma biblioteca para que
possamos adicionar a versão que desejamos. Para isso, em nosso exemplo, utilizaremos
tag exclude colocando o nome da biblioteca que queremos excluir, neste caso, vamos
excluir commons-collection. Para a dependência hibernate-anntoations e myfaces. No
ivy.xml:
<dependencies>
<dependencies>
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 17 | 0 | 0 | 2 || 15 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#agenda
[ivy:retrieve] confs: [default]
[ivy:retrieve] 15 artifacts copied, 0 already retrieved (6833kB/273ms)
Podemos ver que também foram carregados 15 artefatos (de 17 modules) e o conflict
manager escolheu a versão 3.0 do commons-collections.
Resumo
Nesse vídeo vimos como resolver conflitos entre dependências transitivas com ivy. Em
nosso caso, ocorreu um conflito, pois as dependências do Hibernate e MyFaces,
utilizavam a mesma dependência transitiva: a commons-collections, mas em versões
diferentes.
No início da aula vimos como configurar o ivy para simplesmente ignorar as dependências
transitivas, usando o attribute transitive com valor falso.
Outra opção para excluir uma dependência específica, é embutir uma tag exclude.
Atividade 1 de 5
Se mandarmos o Ivy carregar versão 3.5.6-final da dependência hibernate-
annotations com a configuração default, ele carregará também suas dependências
transitivas por padrão. Assim, ao executarmos o comando ant, veremos que o Ivy
carregou 10 artefatos.
O que devemos fazer se não quisermos que o Ivy carregue as dependências transitivas?
17/12/2013 10:55
Atividade 2 de 5
Quando tentamos carregar dependências que tenham as mesmas dependências
transitivas, é possível que ocorra um conflito. Para tentar resolver esse problema, o Ivy
usa um gerenciador de conflitos (conflict-manager) padrão chamado latest-revision,
que carrega apenas a versão mais recente da dependência.
Que linha devemos usar se quisermos que o Ivy carregue todas as dependências?
Atividade 3 de 5
Podemos também fazer com que o build pare e o Ivy não carregue nada caso ocorra um
conflito. Para isso, que conflict manager devemos usar?
Atividade 4 de 5
Qual gerenciador de conflitos (conflict-manager) escolhe a dependência com a versão
mais nova sem abortar o build?
17/12/2013 10:55
strict
latest-compatible
latest-revision
all
latest-time
Atividade 5 de 5
Qual a tag é utilizada para excluir uma dependência transitiva?
17/12/2013 10:56
ignore
skip
delete
evict
exclude
Explicação
Apresentação do projeto
Temos um projeto já pre-configurado no Eclipse. Ele se chama o security-api que possui
uma pasta src para o código fonte com as classes para simular uma biblioteca de
segurança. Dentro do projeto já se encontra a biblioteca do Ivy e os arquivos XMLs
build.xml e ivy.xml.
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<dependencies>
<dependency org="org.springframework" name="spring-core"
rev="3.1.1.RELEASE" conf="default" />
</dependencies>
</ivy-module>
<path id="ivy.lib.path">
<fileset dir="ivy-lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
<target name="clean">
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}" />
</target>
Testando o build
Vamos testar o build.xml na linha de comando com ANT, entrando no workspace e na
pasta do projeto. Podemos mostrar todos os targets disponíveis com o comando:
ant -p
ant jar
Apresenta:
Buildfile: /Users/caelum/Documents/IVY/IVY-workspace/security-api/build.xml
clean:
[delete] Deleting directory /Users/caelum/Documents/IVY/IVY-
workspace/security-api/build
[mkdir] Created dir: /Users/caelum/Documents/IVY/IVY-workspace/security-
api/build
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = /Users/caelum/Documents/IVY/IVY-
workspace/security-api/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: br.com.caelum#security-
api;working@MacBook-Pro-de-Caelum.local
[ivy:retrieve] confs: [default]
[ivy:retrieve] found org.springframework#spring-core;3.1.1.RELEASE
[ivy:retrieve] found org.springframework#spring-asm;3.1.1.RELEASE
[ivy:retrieve] found commons-logging#commons-logging;1.1.1
[ivy:retrieve] :: resolution report :: resolve 273ms :: artifacts dl 5ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 3 | 0 | 0 | 0 || 3 | 0 |
---------------------------------------------------------------------
[ivy:retrieve]
....
compile:
[javac] /Users/caelum/Documents/IVY/IVY-workspace/security-
api/build.xml:27: warning: 'includeantruntime' was not set, defaulting to
build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1 source file to /Users/caelum/Documents/IVY/IVY-
workspace/security-api/build
jar:
[jar] Building jar: /Users/caelum/Documents/IVY/IVY-workspace/security-
api/build/security-api.jar
BUILD SUCCESSFUL
Total time: 2 seconds
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<publications>
<artifact name="security-api" type="jar" ext="jar"/>
</publications>
<dependencies>
<dependency org="org.springframework" name="spring-core"
rev="3.1.1.RELEASE" conf="default" />
</dependencies>
</ivy-module>
<publications>
<artifact name="security-api-jar" type="jar" ext="jar"/>
<artifact name="security-api-javadoc" type="javadoc" ext="jar"/>
</publications>
Publicação e resolvers
Vamos testar o target publish executando o ANT na linha de comando:
ant publish
Com a saída:
.....
jar:
[jar] Building jar: /Users/caelum/Documents/IVY/IVY-workspace/IVY-
repository/security-api/build/security-api.jar
publish:
BUILD FAILED
/Users/caelum/Documents/IVY/IVY-workspace/IVY-repository/security-api/
build.xml:36: no publish deliver name: please provide it through parameter
'resolver'
Podemos ver que o ANT gerou um erro e acusou um parâmetro resolver. O problema é
que Ivy não sabe para onde publicar o nosso JAR. Para isso é preciso criar um arquivo de
configuração, o ivysettings.xml. Este arquivo define esse local do repositório.
No ivy.xml vamos adicionar um elemento ivysettings. Dentro dessa tag vem um outro
elemento resolvers que define o novo repositorio, no nosso caso é baseado no
filesystem local. Vamos dar um nome para esse repositório: ivyrepolocal. Dentro do
filesystem vamos adicionar novamente um pattern para nossos artifacts, definindo o local
onde ficarão os JAR. Veja o ivysettings.xml completo:
<ivysettings>
<settings defaultResolver="ivyrepolocal" />
<resolvers>
<filesystem name="ivyrepolocal">
<artifact pattern="${user.home}/ivyrepolocal/[module]/[artifact]-
[revision].[ext]" />
<ivy pattern="${user.home}/ivyrepolocal/[module]/ivy-[revision].xml"
/>
</filesystem>
</resolvers>
</ivysettings>
O user.home indica a pasta do usuário. Lá dentro será criado uma pasta ivyrepolocal,
seguido por uma pasta com o nome do [module], do [artifact], colocando a [revision]
e a extensão ( [ext] ). Cada artefato é sempre acompanhado pelo um ivy.xml, para isso
também definiremos um ivy pattern.
Além dos patterns foi definido um elemento para declarar o resolver padrão. No nosso
caso é o ivyrepolocal. Finalmente usaremos o nome desse resolver no target publish
do build.xml:
ant publish
Com a saída:
compile:
[javac] /Users/caelum/Documents/IVY/IVY-workspace/IVY-
repository/security-api/build.xml:22:
warning: 'includeantruntime' was not set, defaulting to
build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1 source file to
/Users/caelum/Documents/IVY/IVY-workspace/IVY-repository/security-api/build
jar:
[jar] Building jar:
/Users/caelum/Documents/IVY/IVY-workspace/IVY-repository/security-api/build/
security-api.jar
publish:
[ivy:publish] :: delivering ::
br.com.caelum#security-api;working@MacBook-Pro-de-Caelum.local :: 1.0
:: release :: Wed Aug 15 18:25:23 BRT 2012
[ivy:publish] delivering ivy file to
/Users/caelum/Documents/IVY/IVY-workspace/IVY-repository/security-api/build/
ivy.xml
[ivy:publish] :: publishing :: br.com.caelum#security-api
[ivy:publish] published security-api to
/Users/caelum/ivyrepolocal/security-api/security-api-1.0.jar
[ivy:publish] published ivy to
/Users/caelum/ivyrepolocal/security-api/ivy-1.0.xml
Baixar dependências do
repositório local
O próximo passo é usar essa dependência dentro de um outro projeto. Para isso vamos
criar um novo projeto e chamá-lo de application. Será usado um projeto java comum.
Nesse projeto novo copiaremos o ivy.xml e build.xml e a bibliteco do IVY do projeto
anterior.
O ivy.xml será mais simples e não terá o elemento publications. E nome do modulo
será application, organization continua da mesma forma. A dependência não será mais
o springframework, ela será do módulo security-api na versão 1.0:
<dependencies>
<dependency org="br.com.caelum" name="security-api" rev="1.0"
conf="default" />
</dependencies>
</ivy-module>
<path id="ivy.lib.path">
<fileset dir="ivy-lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
<target name="clean">
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}" />
</target>
ant compile
Buildfile: /Users/admin/dev/IVY-repository/application/build.xml
clean:
[delete] Deleting directory /Users/admin/dev/IVY-
repository/application/build
[mkdir] Created dir: /Users/admin/dev/IVY-repository/application/build
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = /Users/admin/dev/IVY-
repository/application/ivysettings.xml
[ivy:retrieve] :: resolving dependencies ::
br.com.caelum#application;working@admins-MacBook-Air.local
[ivy:retrieve] confs: [default]
[ivy:retrieve] found br.com.caelum#security-api;1.0 in ivyrepolocal
[ivy:retrieve] found org.springframework#spring-core;3.1.1.RELEASE in
ivyrepolocal
[ivy:retrieve] found org.springframework#spring-asm;3.1.1.RELEASE in
ivyrepolocal
[ivy:retrieve] found commons-logging#commons-logging;1.1.1 in
ivyrepolocal
[ivy:retrieve] downloading /Users/admin/ivyrepolocal/security-api/security-
api-1.0.jar ...
[ivy:retrieve] .. (0kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] br.com.caelum#security-api;1.0!security-
api.jar (6ms)
[ivy:retrieve] :: resolution report :: resolve 327ms :: artifacts dl 21ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 4 | 1 | 1 | 0 || 4 | 1 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#application
[ivy:retrieve] confs: [default]
[ivy:retrieve] 1 artifacts copied, 3 already retrieved (0kB/7ms)
compile:
[javac] /Users/admin/dev/IVY-repository/application/build.xml:23:
warning: 'includeantruntime'
BUILD SUCCESSFUL
retrieve ele carrega as dependências por de baixo dos panos. Carregou quatro jars, o JAR
da nossa biblioteca e as dependências transistivas.
O detalhe que não sabemos ainda é que por padrão, o IVY nem olha no repositorio por
padrão. Se o IVY acha dentro da pasta do usuário, uma pasta especial escondida que se
chama .ivy2, ele procura as dependências ali. Esta pasta é um cache local e se o IVY
encontra nesssa pasta os JARs, ele não procurará mais nos repositórios.
Vamos então apagar esta pasta e depois chamar novamento o comando ant compile:
BUILD FAILED
/Users/admin/dev/IVY-repository/application/build.xml:19: impossible to
resolve dependencies:
resolve failed - see output for details
IVY tenta carregar a nossa biblioteca security-api mas não consegue resolver pois
procurou no repositorio padrão, o Maven Repositorio. É claro que nossa biblioteca
recentemente criada não está publicada lá.
Para resolver isso vamos configurar o repositório local dentro do projeto application. Isto
é feito através da mesma configuração já usada dentro do ivysettings.xml. Vamos
adicionar este arquivo no projeto dentro da pasta src:
<ivysettings>
<settings defaultResolver="ivyrepolocal" />
<resolvers>
<filesystem name="ivyrepolocal">
<artifact pattern="${user.home}/ivyrepolocal/[module]/[artifact]-
[revision].[ext]" />
<ivy pattern="${user.home}/ivyrepolocal/[module]/ivy-
[revision].xml" />
</filesystem>
</resolvers>
</ivysettings>
ant compile
Com a saída:
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = /Users/admin/dev/IVY-
repository/application/ivysettings.xml
[ivy:retrieve] :: resolving dependencies ::
br.com.caelum#application;working@admins-MacBook-Air.local
[ivy:retrieve] confs: [default]
[ivy:retrieve] found br.com.caelum#security-api;1.0 in ivyrepolocal
[ivy:retrieve] downloading /Users/admin/ivyrepolocal/security-api/security-
api-1.0.jar ...
[ivy:retrieve] .. (0kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] br.com.caelum#security-api;1.0!security-
api.jar (5ms)
[ivy:retrieve] :: resolution report :: resolve 175ms :: artifacts dl 7ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 2 | 1 | 1 | 0 || 1 | 1 |
---------------------------------------------------------------------
[ivy:retrieve]
[ivy:retrieve] :: problems summary ::
[ivy:retrieve] :::: WARNINGS
[ivy:retrieve] module not found: org.springframework#spring-
core;3.1.1.RELEASE
[ivy:retrieve] ==== ivyrepolocal: tried
[ivy:retrieve] /Users/admin/ivyrepolocal/spring-core/ivy-
3.1.1.RELEASE.xml
[ivy:retrieve] -- artifact org.springframework#spring-
core;3.1.1.RELEASE!spring-core.jar:
[ivy:retrieve] /Users/admin/ivyrepolocal/spring-core/spring-core-
3.1.1.RELEASE.jar
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: UNRESOLVED DEPENDENCIES ::
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: org.springframework#spring-core;3.1.1.RELEASE: not
found
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve]
[ivy:retrieve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
BUILD FAILED
/Users/admin/dev/IVY-repository/application/build.xml:19: impossible to
resolve dependencies: resolve failed - see output for details
Configuração da cadeia de
repositórios
Não foram encontradas as dependências transitivas. Isso ocorreu porque as dependências
transitivas vem do repositório do Maven. Nos definimos apenas um repositório local, agora
é preciso definir tambem o do Maven.
Declararemos um novo resolver que representa o repositório do Maven. Este resolver se
chama ibiblio por padrão. Para usar os dois resolvers, ibiblio e ivyrepolocal, em
conjunto vamos definir uma cadeia de resolvers (chain). Veja como que fica o arquivo
ivysettings.xml:
<ivysettings>
<resolvers>
<chain name="repochain">
<ibiblio m2compatible="true" name="mavenrepo"/>
<filesystem name="ivyrepolocal">
<artifact
pattern="${user.home}/ivyrepolocal/[module]/[artifact]-[revision].[ext]" />
<ivy pattern="${user.home}/ivyrepolocal/[module]/ivy-
[revision].xml" />
</filesystem>
</chain>
</resolvers>
</ivysettings>
Como chain é composto pelo repositório do Maven e nosso repositório local o IVY vai
procurar em ambos lugares as dependências. Repare também que o defaultResolver se
chama repochain.
ant compile
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = /Users/admin/dev/IVY-
repository/application/ivysettings.xml
[ivy:retrieve] :: resolving dependencies ::
br.com.caelum#application;working@admins-MacBook-Air.local
[ivy:retrieve] confs: [default]
[ivy:retrieve] found br.com.caelum#security-api;1.0 in ivyrepolocal
[ivy:retrieve] found org.springframework#spring-core;3.1.1.RELEASE in
mavenrepo
[ivy:retrieve] found org.springframework#spring-asm;3.1.1.RELEASE in
mavenrepo
[ivy:retrieve] found commons-logging#commons-logging;1.1.1 inmavenrepo
[ivy:retrieve] downloading
http://repo1.maven.org/maven2/org/springframework/spring-core/3.1.1.RELEASE/
spring-core-3.1.1.RELEASE.jar ...
[ivy:retrieve] ..............................................................
..........
[ivy:retrieve] ...................
[ivy:retrieve] ............................................
[ivy:retrieve] .................................
[ivy:retrieve] ................................................
[ivy:retrieve] ................................ (438kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] org.springframework#spring-
core;3.1.1.RELEASE!spring-core.jar (10527ms)
[ivy:retrieve] downloading
http://repo1.maven.org/maven2/org/springframework/spring-asm/3.1.1.RELEASE/
spring-asm-3.1.1.RELEASE.jar ...
[ivy:retrieve] ..................................... (51kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] org.springframework#spring-
asm;3.1.1.RELEASE!spring-asm.jar (2133ms)
[ivy:retrieve] downloading
http://repo1.maven.org/maven2/commons-logging/commons-logging/1.1.1/commons-
logging-1.1.1.jar ...
[ivy:retrieve] .......................................... (59kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] commons-logging#commons-logging;1.1.1!
commons-logging.jar (2045ms)
[ivy:retrieve] :: resolution report :: resolve 17028ms :: artifacts dl
14712ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 4 | 3 | 3 | 0 || 4 | 3 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: br.com.caelum#application
[ivy:retrieve] confs: [default]
[ivy:retrieve] 0 artifacts copied, 4 already retrieved (0kB/5ms)
compile:
[javac] /Users/admin/dev/IVY-repository/application/build.xml:23:
warning: 'includeantruntime' was not set, defaulting to
build.sysclasspath=last; set to false for repeatable builds
BUILD SUCCESSFUL
Instalando todas as
dependências no repositório
local
Para nossa aplicação não desejamos usar um repositório publico. Todas as dependências
devem se encontrar dentro do repositório local. Então vamos apagar a cadeia de resolver
dentro de ivysettings.xml e continuar utilizando apenas o repolocal como padrão:
<ivysettings>
<settings defaultResolver="ivyrepolocal" />
<resolvers>
<filesystem name="ivyrepolocal">
<artifact pattern="${user.home}/ivyrepolocal/[module]/[artifact]-
[revision].[ext]" />
<ivy pattern="${user.home}/ivyrepolocal/[module]/ivy-
[revision].xml" />
</filesystem>
</resolvers>
</ivysettings>
Todas as dependências devem estar dentro do repositório local. Para nossa aplicação isso
significa que além do security-api também o spring framework deve ficar no repositório
local.
Há uma tarefa do IVY que podemos usar dentro do build.xml para copiar qualquer
dependência entre repositiórios. No nosso caso queremos copiar o spring framework do
repositório do Maven para o nosso repositório local. A tarefa se chama ivy:install:
<target name="install">
<ivy:install from="mavenrepo" to="ivyrepolocal"
organisation="org.springframework" module="spring-core"
revision="3.1.1.RELEASE" transitive="true" overwrite="true" />
</target>
Aqui declaramos que queremos instalar do (from) mavenrepo para (to) ivyrepolocal,
overwrite=”true” para sobreescrever e definindo a organização, modulo e revisão.
Chamando a tarefa com Ant:
ant install
Mostra a saída:
install:
[ivy:install] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:install] :: loading settings :: file = /Users/admin/dev/IVY-
repository/security-api/ivysettings.xml
[ivy:install] :: installing org.springframework#spring-core;3.1.1.RELEASE ::
[ivy:install] :: resolving dependencies ::
[ivy:install] found org.springframework#spring-core;3.1.1.RELEASE in
mavenrepo
[ivy:install] found org.springframework#spring-asm;3.1.1.RELEASE in
mavenrepo
[ivy:install] found commons-logging#commons-logging;1.1.1 in mavenrepo
[ivy:install] found commons-collections#commons-collections;3.2 in
mavenrepo
[ivy:install] found log4j#log4j;1.2.15 in mavenrepo
[ivy:install] found net.sf.jopt-simple#jopt-simple;3.0 in mavenrepo
[ivy:install] found org.apache.ant#ant;1.7.0 in mavenrepo
[ivy:install] found org.apache.ant#ant-launcher;1.7.0 in mavenrepo
[ivy:install] found org.aspectj#aspectjweaver;1.6.8 in mavenrepo
[ivy:install] :: downloading artifacts to cache ::
[ivy:install] downloading …..........
[ivy:install] .. (0kB)
[ivy:install] [SUCCESSFUL ] org.apache.ant#ant;1.7.0!ant.jar (7431ms)
[ivy:install] downloading http://repo1.maven.org/maven2/org/apache/ant/ant-
launcher/1.7.0/ant-launcher-1.7.0.jar ...
[ivy:install] .......... (11kB)
[ivy:install] .. (0kB)
[ivy:install] [SUCCESSFUL ] org.apache.ant#ant-launcher;1.7.0!ant-
launcher.jar (608ms)
[ivy:install] :: installing in ivyrepolocal ::
[ivy:install] published spring-core to /Users/admin/ivyrepolocal/spring-
core/spring-core-3.1.1.RELEASE.jar
[ivy:install] published spring-core to /Users/admin/ivyrepolocal/spring-
core/spring-core-3.1.1.RELEASE.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/spring-core/ivy-
3.1.1.RELEASE.xml
[ivy:install] published spring-asm to /Users/admin/ivyrepolocal/spring-
asm/spring-asm-3.1.1.RELEASE.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/spring-asm/ivy-
3.1.1.RELEASE.xml
[ivy:install] published commons-logging to
/Users/admin/ivyrepolocal/commons-logging/commons-logging-1.1.1.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/commons-
logging/ivy-1.1.1.xml
[ivy:install] published commons-collections to
/Users/admin/ivyrepolocal/commons-collections/commons-collections-3.2.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/commons-
collections/ivy-3.2.xml
[ivy:install] published log4j to /Users/admin/ivyrepolocal/log4j/log4j-
1.2.15.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/log4j/ivy-
1.2.15.xml
[ivy:install] published jopt-simple to /Users/admin/ivyrepolocal/jopt-
simple/jopt-simple-3.0.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/jopt-simple/ivy-
3.0.xml
[ivy:install] published aspectjweaver to
/Users/admin/ivyrepolocal/aspectjweaver/aspectjweaver-1.6.8.jar
[ivy:install] published ivy to
/Users/admin/ivyrepolocal/aspectjweaver/ivy-1.6.8.xml
[ivy:install] published ant to /Users/admin/ivyrepolocal/ant/ant-
1.7.0.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/ant/ivy-
1.7.0.xml
[ivy:install] published ant-launcher to /Users/admin/ivyrepolocal/ant-
launcher/ant-launcher-1.7.0.jar
[ivy:install] published ivy to /Users/admin/ivyrepolocal/ant-
launcher/ivy-1.7.0.xml
[ivy:install] :: install resolution report ::
[ivy:install] :: resolution report :: resolve 0ms :: artifacts dl 48147ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 9 | 6 | 6 | 0 || 10 | 7 |
---------------------------------------------------------------------
BUILD SUCCESSFUL
Total time: 1 minute 9 seconds
Foram instalados todas as dependências e dependências transitivas no repositório local.
Resumo
Nessa aula vimos como trabalhar com dois repositórios. O primeiro era o repositório
publico do Maven, o segundo um repositório local. O repositório local era preciso porque
criamos uma biblioteca própria e não queríamos disponibilizar ela dentro do repositório
publico do Maven. Usamos a tarefa ivy:publish para publicar o artefato dentro do nosso
repositório local. Dessa maneira outras maquinas e projetos podem declarar a
dependência também referenciando o repositório local. Para definir os repositórios usamos
o arquivo de configuração, ivysettings.xml. Caso quiséssemos ficar independente do
repositório publico do Maven, é preciso instalar todas as dependências e dependências
transitivas no repositório local. Fizemos isso através da tarefa do ivy:install.
Atividade 1 de 6
Como se chama a tarefa do Ivy para publicar as dependências no repositório?
17/12/2013 10:59
publish
push
retrieve
install
Atividade 2 de 6
Como se chama a tarefa para copiar uma dependências entre repositórios?
17/12/2013 11:00
copy
transfer
install
move
Atividade 3 de 6
Por que poderia fazer sentido usar um repositório local apenas acessível para
desenvolvedores da empresa?
Atividade 4 de 6
Dado a seguinte tarefa no build.xml:
<target name="publicar">
<ivy:publish pubrevision="1.0" status="release" overwrite="true"
resolver="ivyrepolocal">
<artifacts pattern="${build.dir}/[artifact].[ext]"/>
</ivy:publish>
</target>
O ivysettings.xml:
<ivysettings>
<settings defaultResolver="ivyrepolocal" />
<resolvers>
<filesystem name="ivyrepolocal">
<artifact pattern="/home/admin/repo/[module]/[artifact]-[revision].
[ext]" />
<ivy pattern="/home/admin/repo/[module]/ivy-[revision].xml" />
</filesystem>
</resolvers>
</ivysettings>
Em que pasta será publicado o modulo security?
Atividade 5 de 6
Qual das seguintes afirmações é verdadeira?
17/12/2013 11:03
Atividade 6 de 6
Baixe o projeto security-api aqui .
Esse projeto está com o build quebrado. Ao executar ant publish na raiz do projeto
percebemos que o build está falhando com a mensagem seguinte:
Buildfile: /Users/caelum/Documents/workspace/security-api/build.xml
........
Conserte o build e crie o ivysettings.xml para definir o resolver. Cole na sua resposta o
arquivo completo.