長 久以下,JAR檔案的管理一直是專案的困擾,到底這個框架相依於哪些JAR檔?而JAR檔案的版本為何?多個框架搭配時,共用的JAR檔版本該如何解決? 如何確認目前的JAR是你指定的版本等?
Apache Ivy 是個相依性管理工具,用來記錄、追蹤、報告專案的相依性,可與Ant緊密結合,運作的方式與 Apache Maven 類似,將各種開放原始碼專案的JAR檔放在網路或本地端的貯藏室(repository)加以管理,開發人員只要列出所需的程式庫或框架,相依性管理工具 就會自動從貯藏室下載相對應且正確的相關JAR檔案。
要在Ant中使用Ivy,只要將下載的ivy-x.x.x.jar(x為版本號)放在Ant的lib目錄中,接著撰寫ivy.xml檔案,列出你所需的程式庫或框架。例如:
<ivy-module version="2.0">
<info organisation="org.apache" module="hello-ivy"/>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.6"/>
<dependency org="commons-logging" name="commons-logging" rev="1.1"/>
</dependencies>
</ivy-module>
在這邊列出來,將下載Commons Lang與Commons Logging及其版本,由於Ivy預設使用 Apache Maven 2的 貯藏室,org、name、rev屬性該放哪些值,可以參考Apache Maven 2的POM設定。例如原本Apache Maven 2中若是如下的POM設定:
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.0</version>
</dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.0</version>
</dependency>
則<groudId> 的值就是設定在Ivy中<dependency>的org的值.<artifactId>的值就是設定name的值,你可以使用 http://mvnrepository.com/ 來查詢相關程式庫的設定。
如果要在Ant的build.xml中使用Ivy下載相依JAR。以下是一個例子:
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="hello-ivy">
<target name="retrieve">
<ivy:retrieve />
</target>
</project>
你在build.xml後宣告XML名稱空間ivy,之後使用retrieve標籤 來開始下載JAR檔案。一個執行的例子如下:
>ant
retrieve
Buildfile: C:\workspace\Demo\build.xml
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/C:/Winware/apache-ant-1.8
2/lib/ivy-2.2.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache#hello-ivy;working@caterp
llar
[ivy:retrieve] confs: [default]
[ivy:retrieve] found commons-lang#commons-lang;2.6 in public
[ivy:retrieve] found commons-logging#commons-logging;1.1 in public
[ivy:retrieve] found log4j#log4j;1.2.12 in public
[ivy:retrieve] found logkit#logkit;1.0.1 in public
[ivy:retrieve] found avalon-framework#avalon-framework;4.1.3 in public
[ivy:retrieve] found javax.servlet#servlet-api;2.3 in public
[ivy:retrieve] downloading http://repo1.maven.org/maven2/commons-logging/common
-logging/1.1/commons-logging-1.1-sources.jar ...
[ivy:retrieve] ................................................................
...................... 略
[ivy:retrieve] :: resolution report :: resolve 26027ms :: artifacts dl 20164ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 6 | 5 | 5 | 0 || 9 | 6 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#hello-ivy
[ivy:retrieve] confs: [default]
[ivy:retrieve] 9 artifacts copied, 0 already retrieved (2902kB/36ms)
BUILD SUCCESSFUL
Total time: 47 seconds
Buildfile: C:\workspace\Demo\build.xml
retrieve:
[ivy:retrieve] :: Ivy 2.2.0 - 20100923230623 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/C:/Winware/apache-ant-1.8
2/lib/ivy-2.2.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache#hello-ivy;working@caterp
llar
[ivy:retrieve] confs: [default]
[ivy:retrieve] found commons-lang#commons-lang;2.6 in public
[ivy:retrieve] found commons-logging#commons-logging;1.1 in public
[ivy:retrieve] found log4j#log4j;1.2.12 in public
[ivy:retrieve] found logkit#logkit;1.0.1 in public
[ivy:retrieve] found avalon-framework#avalon-framework;4.1.3 in public
[ivy:retrieve] found javax.servlet#servlet-api;2.3 in public
[ivy:retrieve] downloading http://repo1.maven.org/maven2/commons-logging/common
-logging/1.1/commons-logging-1.1-sources.jar ...
[ivy:retrieve] ................................................................
...................... 略
[ivy:retrieve] :: resolution report :: resolve 26027ms :: artifacts dl 20164ms
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| default | 6 | 5 | 5 | 0 || 9 | 6 |
---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#hello-ivy
[ivy:retrieve] confs: [default]
[ivy:retrieve] 9 artifacts copied, 0 already retrieved (2902kB/36ms)
BUILD SUCCESSFUL
Total time: 47 seconds
下載的JAR,預設會使用者目錄的.ivy2目 錄中,之後專案有用到的話,會複製一份放在你的lib資料夾中。
在 產生測試報告 中的build.xml,可以改使用Ivy下載JUnit的JAR檔案。例如定義ivy.xml:
<ivy-module version="2.0">
<info organisation="org.apache" module="junit-ivy"/>
<dependencies>
<dependency org="junit" name="junit" rev="4.8"/>
</dependencies>
</ivy-module>
接著定義build.xml:
<project xmlns:ivy="antlib:org.apache.ivy.ant"
name="example" default="report">
<property name="src.dir" value="src"/>
<property name="bin.dir" value="bin"/>
<property name="report.dir" value="report"/>
<ivy:retrieve file="./ivy.xml" sync="true"/>
<property name="junit.dir" value="lib/junit-4.8.jar"/>
<target name="clean">
<delete dir="${bin.dir}"/>
<delete dir="${report.dir}"/>
</target>
<target name="prepare" depends="clean">
<mkdir dir="${bin.dir}"/>
<mkdir dir="${report.dir}"/>
</target>
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${bin.dir}">
<classpath>
<pathelement location="${junit.dir}"/>
</classpath>
</javac>
</target>
<target name="test" depends="compile">
<junit printsummary="yes">
<formatter type="xml"/>
<batchtest todir="${report.dir}">
<fileset dir="${src.dir}" includes="**/*Test.java"/>
</batchtest>
<classpath>
<pathelement location="${bin.dir}"/>
<pathelement location="${junit.dir}"/>
</classpath>
</junit>
</target>
<target name="report" depends="test">
<junitreport todir="${report.dir}">
<fileset dir="${report.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${report.dir}/html"/>
</junitreport>
</target>
</project>
接著只要下ant指令,就會自動為你下載JUnit相關JAR檔、設定相關屬性、編譯、測試、完成報告等動作。