0x000
最近帮公司j2se的同事做了一个加密解密的工具,最后要求打包好jar供他们调用。一直以来都是使用maven来构建j2ee项目,这次面对j2se不得不重新上手ant,而且jenkins做持续化构建对ant支持非常友好。
0x001
基础的不用说,小小总结下一些需要注意的。
1. ant的属性值一旦设定就不能改变,当再次设置时仍会使用原来的值,类似java中的String
<?xml version="1.0"?>
<project name="Hello World Project" default="info">
<property name="test" value="test123" />
<property name="test" value="test456" />
<target name="info">
<echo>
the value of test is ${test}
</echo>
</target>
</project>
显示的值是test123
ant通过命令行方式可以手动添加一些属性的值,更为灵活。
ant -f mybuild.xml -Dtest=test789
不管在xml中有没有设置test的值,都显示test789, 因为-D参数加载在最前面。
这一点同样的在jenkins中可以利用,如下图中的property其实转化到最终命令行就-D,可以用来更改文件版本之类,不管xml中是否已经定义。
2.ant默认记载目录中的build.xml文件,但是可以通过-f参数来指定加载任意文件。
3.ant操作涉及到目录,所以需要指定根目录,方便后边文件和目录的操作,避免引用全路径。如下指定根目录为项目根目录
<project basedir=".">
</project>
4.ant兼容win和linux路径, 定义路径使用location
<property name="mydir" location="${basedir}/dit/test.jar" />
其会在不同系统中自动转换分隔符
0x002
一些常用标签
编译源代码 javac
<target name="complier">
<!--通常在另外一个目录下生成class,便于管理和打包-->
<mkdir dir="bin" />
<javac srcdir="src" desdir="bin"></javac>
</target>
创建jar
<target name="package">
<jar basedir="bin" destfile="dist/package.jar"></jar>
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="com.example.test"/>
</manifest>
</target>
时间戳生成 tstamp
<!--直接使用一个标签,后面就可以使用-->
<tstamp />
<target>
<echo>
${DSTAMP}, ${TSTAMP}, ${TODAY}
</echo>
</target>
20160220, 1314, February 20 2016
文件系统操作
<target>
<mkdir dir="${basedir/xx/xx}" />
<delete file="xx.jar"/>
<delete dir="${basedir}/xx"/>
<copy file="src/Test.java" tofile="src_test/Test_copy.java" />
<copy file="src/Test.java" todir="src_test" />
<move file="src/Test.java" tofile="src_test/Test_move.java" />
<move file="src/Test.java" todir="src_test" />
</target>
创建和解压缩zip文件
<target>
<zip destfile="dist/package.zip" basedir="bin"/>
<unzip dest="src" src="dist/package.zip"/>
</target>
替换文件中的文字
<target>
<replace file="input.txt" token="oldchar" value="newchar" summary="true"/>
<!--summary="true"会输出替换数目等详细信息-->
</target>
模式匹配
*任意一个
src*/*.java src开头目录里所有的java
**它匹配任意数量的目录
**/*.java当前目录下所有的java
<copy todir="bin">
<fileset dir="src">
<include file="**/*.java"/>
</fileset>
</copy>
fileset 默认指定dir目录的所有文件,需要指定include, exclude元素来排除和包含文件,可以多个这样的元素。include的并集排除exclude所有的匹配
我最后的脚本
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="build runnable CryptoTools.jar with Ant" default="build-jar">
<!--
工程目录结构
project
|-classes 默认class文件目录
|-src java源文件目录
|-lib 第三方jar包目录
|-dist 打包后jar目录
|-bin Ant编译时class临时目录,clean时删除
|-build.xml Ant脚本
=============================================
修改${jar.ver}的版本信息
=============================================
命令
ant [build-jar] : (default)打包jar
ant clean: 删除打包产生的jar和bin目录
ant rerun: clean + build-jar
打包方式
将第三方jar直接打包进要生成的jar, 需要引进一个jar-in-jar.zip文件
=============================================
-->
<description>build jar with Ant</description>
<!--版本 vx.x eg: v3.4-->
<property name="jar.ver" value="v4.0"/>
<property name="jar.name" value="CryptoTools.jar"/>
<!--用于保存CryptoTools.jar的目录,默认为${basedir}/dist/x.x,-->
<property name="build.dir" value="${basedir}/dist/${jar.ver}"/>
<!--java源文件目录-->
<property name="src.dir" value="${basedir}/src"/>
<property name="src.lib" value="${basedir}/lib"/>
<!--编译为class的临时文件目录-->
<property name="des.dir" value="${basedir}/bin"/>
<!--第三方jar包路径-->
<path id="lib-classpath">
<fileset dir="${src.lib}">
<include name="*.jar"/>
</fileset>
</path>
<!--初始化操作-->
<target name="init">
<mkdir dir="${des.dir}"/>
</target>
<!--编译操作,不管是否运行过,确保编译生成class文件用于打包-->
<target name="complier" depends="init">
<javac srcdir="${src.dir}" destdir="${des.dir}" includeantruntime="on" >
<classpath refid="lib-classpath"/>
</javac>
</target>
<!--默认的,打包jar文件-->
<target name="build-jar" description="build a jar" depends="complier,prep">
<jar excludes="*Test*.class" destfile="${build.dir}/${jar.name}">
<manifest>
<!--多了Rsrc-Main-Class和Rsrc-Class-Path这两个属性-->
<attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>
<attribute name="Rsrc-Main-Class" value="com.wizarpos.crypto.util.SignImage"/>
<attribute name="Class-Path" value="."/>
<attribute name="Rsrc-Class-Path" value="./ not-yet-commons-ssl-0.3.11.jar bcprov-jdk15on-154.jar"/>
</manifest>
<!--引入 jar-in-jar-loader-->
<zipfileset src="jar-in-jar-loader.zip"/>
<fileset dir="${des.dir}"/>
<zipfileset dir="${src.lib}" includes="not-yet-commons-ssl-0.3.11.jar"/>
<zipfileset dir="${src.lib}" includes="bcprov-jdk15on-154.jar"/>
</jar>
</target>
<!--运行测试jar文件
<target name="run-jar">
<java classname="example.HelloWorld" classpath="${build.dir}/${jar.name}"></java>
</target>
-->
<!--复制必要的文件和创建目录-->
<target name="prep">
<mkdir dir="${build.dir}"/>
<copyfile dest="${build.dir}/simg2img" src="${basedir}/simg2img"/>
</target>
<!--清除任务文件-->
<target name="clean">
<delete dir="${des.dir}" />
<delete file="${build.dir}/${jar.name}" />
<delete dir="${build.dir}" />
</target>
<!--重新运行任务-->
<target name="rerun" depends="clean,build-jar">
<ant target="clean" />
<ant target="build-jar" />
</target>
</project>