Maven 依賴管理強大但標準打包僵化;Ant 靈活但缺乏依賴管理。Maven Ant Task 完美融合兩者:在 Ant 腳本中加載 POM、解析依賴、獲取構建路徑,再用 Ant 任務實現任意打包邏輯。本文完整記錄從項目結構、POM 配置、build.xml 編寫到執行的全過程。
anttaskdemo1.zip
├── run.bat / run.sh
├── lib/ (含項目 jar + runtime 依賴)
├── config/ (外部配置)
└── log/
anttaskdemo1/
├── src/main/java
├── src/main/resources # 打入 jar 的 classpath 資源
├── src/main/config # 外部化配置
├── src/main/bin # 啟動腳本
├── src/test/...
├── target/
├── build.properties # 路徑變量
├── build.xml # Ant 腳本
└── pom.xml
<dependencies>
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.3</version> </dependency>
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.13</version> <scope>compile</scope> </dependency>
<dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>5.8</version> <scope>test</scope> <classifier>jdk15</classifier> </dependency>
</dependencies>
注意 testng 設置 scope=test,不參與 runtime 依賴解析。
M2_REPO=G:/soft/maven/localRepository
path.package=package
path.target.name=anttaskdemo1
path.package.lib=lib
path.package.config=config
path.package.log=log
path.package.bin=
<target name="init_maven">
<!-- 載入 maven-ant-tasks.jar,兩種方式二選一 -->
<path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar"/>
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath"/>
<!-- 加載 POM -->
<artifact:pom id="maven.project" file="pom.xml"/>
<!-- 解析 compile 依賴(用於編譯) -->
<artifact:dependencies pathId="classpath.build" filesetId="maven.fileset.build">
<pom refid="maven.project"/>
</artifact:dependencies>
<!-- 解析 runtime 依賴(用於打包 lib) -->
<artifact:dependencies pathId="classpath.runtime" filesetId="maven.fileset.runtime" useScope="runtime">
<pom refid="maven.project"/>
</artifact:dependencies>
</target>
M2_REPO 可通過 Eclipse 全局變量或 properties 文件設置,優雅解決 jar 存放位置問題。
<target name="compile" depends="init_maven">
<javac srcdir="${maven.project.build.sourceDirectory}"
destdir="${maven.project.build.outputDirectory}"
classpathref="classpath.build"/>
</target>
<target name="jar" depends="compile,copyResource">
<jar destfile="${maven.project.build.directory}/${maven.project.build.finalName}.jar"
basedir="${maven.project.build.outputDirectory}"/>
</target>
<target name="copyLib" depends="init_maven">
<!-- 複製 runtime 依賴 -->
<copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}">
<fileset refid="maven.fileset.runtime"/>
<mapper type="flatten"/> <!-- 去除版本號目錄結構 -->
</copy>
<!-- 複製項目自身 jar -->
<copy file="${target.jar.name}" todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"/>
</target>
<target name="copyConfig" depends="init_maven">
<copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}">
<fileset dir="src/main/config"/>
</copy>
</target>
<target name="copyBin" depends="init_maven">
<copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.bin}">
<fileset dir="src/main/bin"/>
</copy>
</target>
<target name="zip" depends="init_maven">
<zip destfile="${maven.project.build.directory}/${path.package}/${path.target.name}.zip">
<fileset dir="${maven.project.build.directory}/${path.package}/${path.target.name}"/>
</zip>
</target>
# Eclipse: 右鍵 build.xml → Run As → Ant Build → 選擇 all target
# 命令行:
ant -f build.xml all
產物:target/package/anttaskdemo1.zip,結構完全符合預期。
M2_REPO 變量優雅引用本地倉庫中的 maven-ant-tasks.jarPOM 中 <resources> 多 <resource> 子元素時,Ant 難以動態獲取各 <directory>,示例中簡化為固定 src/main/resources。複雜場景建議遷移至 Assembly Plugin。