用Apache Ivy實現專案裡的依賴管理
Apache Ivy是一個管理專案依賴的工具。
它與Maven
Apache Maven 構建管理和專案管理工具已經吸引了 Java 開發人員的注意。Maven 引入了 JAR 檔案公共儲存庫的概念,可通過公開的 Web 伺服器訪問(稱為 ibiblio)。Maven 的方法減少了 JAR 檔案膨脹的情況,不會佔用大多數版本控制儲存庫。但使用 Maven 時,它會鼓勵您採用其 “慣例優於配置” 的方法來構建軟體,這會制約您定製構建指令碼的靈活性。
但問題是Maven過於Heavy,而大部分已有的專案都用Ant做build,所以Ivy是更加合適的選擇。
Ivy 提供了最一致、可重複、易於維護的方法,來管理專案的所有構建依賴項。
用Ivy進行專案管理
開始使用 Ivy 非常簡單,只需建立兩個 Ivy 特有的檔案,新增一些 Ant 目標即可。Ivy 特有的檔案是 ivy.xml 和一個 Ivy 設定檔案。ivy.xml 檔案中列舉了專案的所有依賴項。ivysettings.xml 檔案(可以隨意為此檔案命名)用於配置從中下載有依賴關係的 JAR 檔案的儲存庫。
Ivy的安裝
Ivy依賴於Ant,所以需要先安裝Ant,然後下載Ivy,將他的jar檔案考到Ant的lib下面,就可以在Ant裡使用Ivy進行依賴管理了。
下載ivy 2.0
下載好後安裝它,把它解壓到f:/ivy-2.0.0(把此目錄認為是IVY_HOME),把IVY_HOME/ivy-2.0.0.jar放到 ANT_HOME/lib目錄下。然後命令列入到IVY_HOME/src/example/hello-ivy目錄,執行ant。然後它會下載依賴的所有jar包。
看下hello-ivy的依賴配置:
1. <ivy-module version="2.0">
2. <info organisation="org.apache" module="hello-ivy"/>
3. <dependencies>
4. <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
5. <dependency org="commons-cli" name="commons-cli" rev="1.0"/>
6. </dependencies>
7. </ivy-module>
依賴commons-lang-2.0.jar 和 commons-cli-1.0.jar,ivy會自動下載,當然還有這些*.jar所依賴的jar, 如這裡的commons-cli-1.0.jar依賴commons-logging-1.0.jar,不用在ivy.xml檔案定義。它們已經在lib 目錄下了。
然後你再一次執行ant,ivy不會再下載這些jar,因為本地有快取了。
當然也可以用ant report任務,輸出jar依賴報告,預設在build目錄,org.apache-hello-ivy-default.html。
延伸:預設快取目錄為${user.home}/cache。你也可以改它的預設目錄在執行ant時,設定,如ivy.default.ivy.user.dir=f:/ivy2,所以它會快取到f:/ivy2/cache
使用Ivy
ivy.xml
在 ivy 中,配置(conf)是比較重要的概念,它對應一組依賴的jar。比較一個編譯期間的conf(compile),它依賴commons-lang。執行期間它還要依賴log4j,可以定義一個執行期配置(runtime),它擴充套件compile。配置是可以擴充套件的,依次類推,可以定義一個測試用的jar 依賴配置(test),它擴充套件runtime。
ivy的jar依賴配置在ivy.xml檔案裡定義與說明,類似:
1. <ivy-module version="1.0">
2. <info organisation="com.chenlb" module="ivy-hello"/>
3.
4. <configurations>
5. <conf name="compile" visibility="private" description="compilation only need jar" />
6. <conf name="runtime" visibility="private" extends="compile" description="for runtime need jar" />
7. <conf name="test" visibility="private" extends="runtime" description="for test" />
8. <conf name="default" visibility="public" extends="runtime" description="default jar" />
9. </configurations>
10. <dependencies>
11. <dependency org="commons-lang" name="commons-lang" rev="2.1" conf="compile->default"/>
12. <dependency org="log4j" name="log4j" rev="1.2.12" conf="runtime->default"/>
13.
14. <dependency org="junit" name="junit" rev="3.8.2" conf="test->default"/>
15. </dependencies>
16. </ivy-module>
上面定義了,compile、runtime、test、default配置(一個配置對應一個jar依賴集)。compile只依賴 commons-lang-2.1.jar;但runtime還依賴log4j-1.2.12.jar;測試用的還依賴junit-3.8.2.jar。
在Ant裡使用ivy。
加ivy的xmlns。如
1. <project name="ivy-hello" default="init" xmlns:ivy="antlib:org.apache.ivy.ant">
2. <!-- ... -->
3. </project>
下載jar。
1. <target name="resolve" description="--> retreive dependencies with ivy">
2. <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
3. </target>
ivy.lib.dir預設是當前目錄下的lib。[conf]是配置名。[artifact]是jar釋出的名,[revision]是版本號,[ext]是副檔名。
classpath
1. <path id="build.lib.path">
2. <fileset dir="${lib.dir}/build" />
3. </path>
4. <path id="test.lib.path">
5. <fileset dir="${lib.dir}/test" />
6. <pathelement location="${build.java.dir}" />
7. </path>
可以在編譯任務用${compile.lib.path}的classpath,test的也同樣。
現在可以基本執行ant 和 ivy了,執行ant resolve就可以看到ivy下載相關的jar包。
如何構建自己的Repository
Ivy的例子裡已經包括了一個構建repo的例子,在build-a-ivy-repository裡,主要執行build.xml就可以構建一個簡單的repo,如果你想用namespace管理一個專業的repo,可以執行ant maven2-namespace,就會在本地構建一個專業的repo。
Repo-Location/[org]/[name]/ivy-[version].xml
e.g. apache/commons-lang/
contains a jar and a definition file, ivy-[version].xml
下面我們看看ivy-[version].xml裡是什麼內容
<info organisation="apache"module="commons-lang"
revision="1.0"
status="release"
publication="20051124132021"
namespace="maven2">
<description homepage="">
.....
</description>
<m:maven.plugins>nullmaven-surefire-plugin null</m:maven.plugins>
</info>
<configurations>
<conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
<conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
.....
</configurations>
<publications>
<artifact name="commons-lang" type="jar" ext="jar" conf="master"/>
<artifact name="commons-lang" type="javadoc" ext="jar" conf="javadoc" m:classifier="javadoc"/>
</publications>
<dependencies>
<dependency org="junit" name="junit" rev="3.7" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
</dependencies>
</ivy-module>
其實他和普通的ivy.xml的格式是一樣,只是用於定義jar本身的依賴,只是多了publication對提供的jar進行描述。
IVY的配置 - ivysettings.xml
ivy本身有3中repo的型別:local,shared和public的。
ivy預設的setting:在jar裡org.apache.ivy.core.setting包中
<ivysettings> <settings defaultResolver="default"/> <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/> <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/> <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/> <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/> <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/> </ivysettings> 你可以在這裡將public的repo改為你自己的repo <include url="http://myserver/ivy/myivysettings-public.xml "/> myivysettings-public.xml <ivysettings> <resolvers> <filesystem name="public"> <ivy pattern="/path/to/my/public/rep/[organisation]/[module]/ivy-[revision].xml" /> <artifact pattern="/path/to/my/public/rep/[organisation]/[module]/[artifact]-[revision].[ext]" /> </filesystem> </resolvers> </ivysettings> 這樣當resolve是,ivy會先從user local,然後是shared,然後會在你設定的public repo下載jar。 更多的關於Ivy的資訊請查閱Apache Ivy的官方doc: http://ant.apache.org/ivy/