这个示例将举例说明在两个项目之间的依赖。
depender项目声明它使用dependee 项目。我们将阐明两个事情:
* 被独立的项目声明的公共类库将被依赖的项目自动获取
* depender项目将获取dependee项目的"最新"版本
1) 使用到的项目
1. dependee
dependee项目非常简单。它依赖apache类库commons-lang并只包含一个类: standalone.Main : standalone.Main提供两个服务:
* 返回项目的版本
* 使用org.apache.commons.lang.WordUtils.capitalizeFully大写一个字符串
这里是项目的内容:
* build.xml: 项目的ant构建文件
* ivy.xml: 项目的ivy文件
* src\standalone\Main.java: 项目仅有的一个类
看一下ivy.xml文件:
<ivy-module version="1.0">
<info organisation="org.apache" module="dependee"/>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0"/>
</dependencies>
</ivy-module>
ivy依赖文件只声明了一个依赖apache commons-lang类库。
2) depender
项目depender也非常简单。它仅仅声明了一个对dependee项目的最新版本的依赖,而它仅仅包含一个类depending.Main,干了两件事情:
* 通过对 standalone.Main.getVersion() 的调用获取独立项目的版本。
* 通过对standalone.Main.capitalizeWords(str)的调用转换字符串
看一下ivy.xml文件:
<ivy-module version="1.0">
<info organisation="org.apache" module="depender"/>
<dependencies>
<dependency name="dependee" rev="latest.integration" />
</dependencies>
</ivy-module>
2) 设置
ivy设置在settings目录下,包含两个文件:
* ivysettings.properties: 属性文件
* ivysettings.xml: 包含设置的文件
让我们看一下ivysettings.xml文件:
<ivysettings>
<properties file="${ivy.settings.dir}/ivysettings.properties"/>
<settings defaultCache="${ivy.settings.dir}/ivy-cache" defaultResolver="libraries"/>
<resolvers>
<filesystem name="projects">
<artifact pattern="${repository.dir}/[artifact]-[revision].[ext]" />
<ivy pattern="${repository.dir}/[module]-[revision].xml" />
</filesystem>
<ibiblio name="libraries" m2compatible="true" usepoms="false" />
</resolvers>
<modules>
<module organisation="org.apache" name="dependee" resolver="projects"/>
</modules>
</ivysettings>
文件包含四个主要标签:properties, settings, resolvers 和 modules.
1. properties
这个标签仅仅如ant所做的那样为ivy程序装载一些属性。
2. settings
这个标签负责初始化一些为ivy程序使用的参数。ivy用于缓存制品的目录将是包含vysettings.xml文件的目录自身的名为ivy-cache的子目录。
第二个参数,告诉ivy使用一个名为"libraries"的解析器作为默认解析器。更多的信息可以再设置参考文档中找到。
3. resolvers
这个标签定义要使用的解析器。这里我们有两个定义要的解析器:"projects" 和 "libraries".
名为"projects"的文件系统解析器可以通过在本地文件系统中定位依赖来解析内部依赖。
名为"libraries"的ibiblio解析器用于查找在maven2 仓库内的依赖,但是不使用maven poms。
4. modules
modules标签容许配置用哪个解析器来解析哪个依赖。这个实际上只对应于一个模块,但是可以使用正则表达式,或者其他类型的表达式(如glob 表达式)。
对于其他模块(例如所有不是org.apache#dependee的模块),因为这里没有特别设置,将使用默认解析器: "libraries".
3) walkthrough
step 1 : 准备
打开一个dos或者shell窗口,并进入"src/example/dependence"目录
step 2 : 清理
在提示符下: ant
这将清理整个项目目录树(已编译的类和获得的libs)和ivy缓存。你可以再每次你想清理这个例子时做这个事情。
step 3 : 发布dependee项目
进入depende目录,并发布项目
I:\dependee>ant publish
Buildfile: src\example\dependence\standalone\build.xml
resolve:
[ivy:retrieve] :: Ivy 2.0.0-beta1-local-20071104204849 - 20071104204849 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: [ org.apache | standalone | working@BEN-ScokartG ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] found [ commons-lang | commons-lang | 2.0 ] in libraries
[ivy:retrieve] downloading http://www.ibiblio.org/maven/commons-lang/jars/commons-lang-2.0.jar ...
[ivy:retrieve] ......................................
[ivy:retrieve] ...................................... (165kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] [ commons-lang | commons-lang | 2.0 ]/commons-lang.jar[jar] (5388ms)
[ivy:retrieve] :: resolution report ::
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 1 | 1 | 0 | 0 || 1 | 1 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: [ org.apache | standalone ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] 1 artifacts copied, 0 already retrieved
compile:
[mkdir] Created dir: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\classes
[javac] Compiling 1 source file to C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\classes
jar:
[propertyfile] Creating new property file: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\classes\version.properties
[jar] Building jar: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\standalone.jar
publish:
[ivy:publish] :: delivering :: [ org.apache | standalone | working@BEN-ScokartG ] :: 1 :: release :: Sun Nov 04 20:50:24 CET 2007
[ivy:publish] delivering ivy file to C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone/build/ivy.xml
[ivy:publish] :: publishing :: [ org.apache | standalone ]
[ivy:publish] published standalone to C:\dev\data\opensource_workspace\ivy\src\example\dependence\config/repository/standalone-1.jar
[ivy:publish] published ivy to C:\dev\data\opensource_workspace\ivy\src\example\dependence\config/repository/standalone-1.xml
[echo] project standalone released with version 1
BUILD SUCCESSFUL
Total time: 11 seconds
这里我们可以看到:
* 项目依赖1个类型(1个制品)
* 这个类库不再ivy缓存中并且因此被下载 (1 downloaded)
* 这个项目被发行,版本号为1
给了给出关于publish的更多的解析,如你所见publish任务的调用导致了两个主要事情:
* 交付被解析的ivy文件到build/ivy.xml
这个被完成时因为默认publish任务不仅仅发行制品们而且也发行ivy文件。因此它查看ivy文件应该被发行到的路径,使用artifactspattern: ${build.dir}/[artifact].[ext].
对于一个ivy文件,这将解析到build/ivy.xml。因为这个文件不存在,它自动调用deliver任务交付一个被解析的ivy文件到这个目的地。
* 制品dependee的发行和ivy文件到仓库
都仅仅是在当前项目中找到的文件拷贝,更明确的在build目录中。这是因为artifactspattern 被设置为${build.dir}/[artifact].[ext],因此dependee 制品分布在build/dependee.jar而ivy文件在build/ivy.xml. 并且因为我们要求publish任务使用"projects"解析器发行他们,这些文件被复制到repository\dependee-1.jar 和 repository\dependee-1.xml,遵守我们设置中的artifact和ivy模式。
step 4: 运行depender
进入depender目录并运行ant
I:\depender>ant
Buildfile: src\example\dependence\depending\build.xml
clean:
resolve:
[ivy:retrieve] :: Ivy 2.0.0-beta1-local-20071104204849 - 20071104204849 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: [ org.apache | depending | working@BEN-ScokartG ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] found [ org.apache | standalone | 1 ] in projects
[ivy:retrieve] [1] [ org.apache | standalone | latest.integration ]
[ivy:retrieve] found [ commons-lang | commons-lang | 2.0 ] in libraries
[ivy:retrieve] downloading C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\repository\standalone-1.jar ...
[ivy:retrieve] .. (1kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] [ org.apache | standalone | 1 ]/standalone.jar[jar] (20ms)
[ivy:retrieve] :: resolution report ::
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 2 | 1 | 0 | 0 || 2 | 1 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: [ org.apache | depending ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] 2 artifacts copied, 0 already retrieved
compile:
[mkdir] Created dir: C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending\build\classes
[javac] Compiling 1 source file to C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending\build\classes
run:
[java] you are using version 1 of class standalone.Main
[java] standard message : i am depending.Main and standalone.Main will do the job for me
[java] [standalone.Main] capitalizing string "i am depending.Main and standalone.Main will do the job for me" using org.apache.commons.lang.WordUtils
[java] capitalized message : I Am Depending.main And Standalone.main Will Do The Job For Me
BUILD SUCCESSFUL
Total time: 3 seconds
这里我们看到:
* 项目依赖2个类库(2个制品)
* 类库中的一个在缓存中因为仅有一个被下载(1 downloaded)
* ivy得到项目dependee的版本1. 对standalone.Main.getVersion()的调用返回1.如果你查看depender/lib目录,你将看到dependee-1.jar,这是项目dependee的版本1的制品。
* 对standalone.Main.capitalizeWords(str)的调用成功,这意味着在classpath中有需要的类库。如果你查看lib目录,你将看到类库commons-lang-2.0.jar已经被获取。这个类库是项目"dependee"声明要使用的,因此ivy同样为了depender项目而获得它。
step 5: dependee 项目的新版本
和我们在步骤3中做的类型,再次发行dependee项目。这将导致这个项目的新版本。
现在如果你查看你的仓库文件夹,你将发现dependee项目发行的2个版本。
让我们看这个:
I:\dependee>ant publish
Buildfile: src\example\dependence\standalone\build.xml
resolve:
[ivy:retrieve] :: Ivy 2.0.0-beta1-local-20071104204849 - 20071104204849 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: [ org.apache | standalone | working@BEN-ScokartG ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] found [ commons-lang | commons-lang | 2.0 ] in libraries
[ivy:retrieve] :: resolution report ::
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 1 | 0 | 0 | 0 || 1 | 0 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: [ org.apache | standalone ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] 0 artifacts copied, 1 already retrieved
compile:
jar:
[propertyfile] Updating property file: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\classes\version.properties
[jar] Building jar: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\standalone.jar
publish:
[delete] Deleting: C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone\build\ivy.xml
[ivy:publish] :: delivering :: [ org.apache | standalone | working@BEN-ScokartG ] :: 2 :: release :: Sun Nov 04 20:50:33 CET 2007
[ivy:publish] delivering ivy file to C:\dev\data\opensource_workspace\ivy\src\example\dependence\standalone/build/ivy.xml
[ivy:publish] :: publishing :: [ org.apache | standalone ]
[ivy:publish] published standalone to C:\dev\data\opensource_workspace\ivy\src\example\dependence\config/repository/standalone-2.jar
[ivy:publish] published ivy to C:\dev\data\opensource_workspace\ivy\src\example\dependence\config/repository/standalone-2.xml
[echo] project standalone released with version 2
BUILD SUCCESSFUL
Total time: 2 seconds
好,现在我们的仓库包含了dependee项目的2个版本,其他项目可以关联到任何版本。
I:\dependee>dir ..\settings\repository /w
[.] [..] dependee-1.jar dependee-1.xml dependee-2.jar dependee-2.xml
I:\dependee>
step 6: 在depender项目中获取新版本
再次运行depender项目时我们会期望什么?有两个主要事情:
* 获得项目dependee的版本2作为latest.integration 版本
* 运行测试必须显示项目dependee的版本为2
让我们试试吧!
I:\depender>ant
Buildfile: src\example\dependence\depending\build.xml
clean:
[delete] Deleting 3 files from C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending
[delete] Deleted 4 directories from C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending
resolve:
[ivy:retrieve] :: Ivy 2.0.0-beta1-local-20071104204849 - 20071104204849 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: [ org.apache | depending | working@BEN-ScokartG ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] found [ org.apache | standalone | 2 ] in projects
[ivy:retrieve] [2] [ org.apache | standalone | latest.integration ]
[ivy:retrieve] found [ commons-lang | commons-lang | 2.0 ] in libraries
[ivy:retrieve] downloading C:\dev\data\opensource_workspace\ivy\src\example\dependence\config\repository\standalone-2.jar ...
[ivy:retrieve] .. (1kB)
[ivy:retrieve] .. (0kB)
[ivy:retrieve] [SUCCESSFUL ] [ org.apache | standalone | 2 ]/standalone.jar[jar] (100ms)
[ivy:retrieve] :: resolution report ::
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 2 | 1 | 0 | 0 || 2 | 1 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: [ org.apache | depending ]
[ivy:retrieve] confs: [default]
[ivy:retrieve] 2 artifacts copied, 0 already retrieved
compile:
[mkdir] Created dir: C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending\build\classes
[javac] Compiling 1 source file to C:\dev\data\opensource_workspace\ivy\src\example\dependence\depending\build\classes
run:
[java] you are using version 2 of class standalone.Main
[java] standard message : i am depending.Main and standalone.Main will do the job for me
[java] [standalone.Main] capitalizing string "i am depending.Main and standalone.Main will do the job for me" using org.apache.commons.lang.WordUtils
[java] capitalized message : I Am Depending.main And Standalone.main Will Do The Job For Me
BUILD SUCCESSFUL
Total time: 5 seconds
很好,我们得到了期望的结果,run target展示我们正在使用项目dependee的main类的版本2.如果我们看一下resolve target的结果,我们可以看到一个制品从ivy缓存中被下载。实际上这个文件就是从仓库中得到的项目dependee的版本2,你现在可以在ivy-cache目录中得到它。