Ant学习笔记(更新中~)
序言:
出于项目构建自动化的目的,为此学习ant。希望在学习ant的过程中,多自我总结一些ant使用的好处。
1.ant的环境搭建
虽然看似极为简单的操作,但长时间不用的话,也会让人头疼。
步骤1:下载ant环境
步骤2:配置系统path路径,配置方式极像JDK环境的配置。
在开发工具例如:在Myeclipse中,最好重新设置下ant的home路劲。为了不使用开发工具自带的ant包。这一点操作非常像tomcat的路径设置。
附图:
2.编译普通JAVA项目的步骤
按以下标准来对项目进行构建
1.创建文件夹
build->所有文件信息的保存在这个文件中
src->所有的源码信息保存在这个文件中
classes->编译好的所有文件保存在这个文件中
dist->编译好的jar文件保存在这个文件中
2.编译源代码
3.将源码包打包为jar
4.直接运行程序
├─build
│ ├─classes
│ ├─dist
│ └─src
3.简单的Javademo项目进行ant构建
demo项目目录结构:
build.xml配置(这个还有待优化):
<?xml version="1.0" encoding="UTF-8"?>
<project default="execute">
<!--文件集-
ps:
相当于一个常量,可通过id来对该文件集进行引用,可包含和可排除
-->
<fileset id="src.id" dir="src">
<include name="**/*.*"/>
<exclude name="**/Ant*"/>
</fileset>
<!--1.创建文件夹-->
<target name="create">
<delete dir="build" />
<mkdir dir="build"/>
<mkdir dir="build/src"/>
<mkdir dir="build/classes"/>
<mkdir dir="build/dist"/>
</target>
<!--2.拷贝JAVA源码
ps:如果目标目录已经存在,则不会执行
-->
<target name="copySrc" depends="create">
<copy todir="build/src" >
<fileset refid="src.id"></fileset>
</copy>
</target>
<!--3.编译源文件
ps:基于copy源文件操作的基础上
-->
<target name="complier" depends="copySrc">
<javac srcdir="build/src" destdir="build/classes"></javac>
</target>
<!--4.打包成jar
ps:为了直接运行jar包,在jar包中MANIFEST.MF增加:Main-Class:XXXX
-->
<target name="jar" depends="complier">
<jar destfile="build/dist/hello.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="com.techbirds.HelloAnt"/>
<attribute name="Build_By" value="Techbirds"/>
</manifest>
</jar>
</target>
<!--5.最终执行
方法1:基于build/classes中的编译文件进行执行
方法2:基于jar文件进行执行 ps:必须设置fork:true
-->
<target name="execute" depends="jar">
<echo>1.基于build/classes中的编译文件进行执行</echo>
<java classname="com.techbirds.HelloAnt" classpath="build/classes">
<arg value="techbirds"/>
</java>
<echo>2.基于jar文件进行执行 ps:必须设置fork:true</echo>
<java jar="build/dist/hello.jar" fork="true">
<arg value="techbirds"/>
</java>
</target>
</project>
build-update.xml(优化后)
<?xml version="1.0" encoding="UTF-8"?>
<project default="execute">
<!--
涉及到路径的最好都不要用value="xxx",而使用location="xxx/xxx"
ps:因为考虑到不同的os对于路径斜杠的定义是不同的,而location会自动内部处理
注:路径用loaction,值用value
-->
<property name="build.dir" location="build"/>
<property name="src.dir" location="${build.dir}\src"/>
<property name="classes.dir" location="${build.dir}\classes"/>
<property name="dist.dir" location="${build.dir}\dist"/>
<property name="jar" location="${dist.dir}/hello.jar"/>
<property name="main-class" value="com.techbirds.HelloAnt"/>
<property name="author" value="Techbirds"/>
<!--当propery很多时,可引用外部文件
ps:但是路径最好不要在外部文件中定义,因为此时不会location
-->
<property file="build-update.properties"></property>
<property environment="env"></property>
<!--控制台输出-->
<target name="echo">
<echo>${src.dir}</echo>
<echo>${ant.home}</echo>
<echo>${ant.version}</echo>
<echo>${ant.project.name}</echo>
<echo>${env.HOMEPATH}</echo>
</target>
<!--文件集-
ps:
相当于一个常量,可通过id来对该文件集进行引用,可包含和可排除
-->
<fileset id="src.id" dir="src">
<include name="**/*.*"/>
<exclude name="**/Ant*"/>
</fileset>
<!--1.创建文件夹-->
<target name="create" depends="echo">
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}"/>
<mkdir dir="${src.dir}"/>
<mkdir dir="${classes.dir}"/>
<mkdir dir="${dist.dir}"/>
</target>
<!--2.拷贝JAVA源码
ps:如果目标目录已经存在,则不会执行
-->
<target name="copySrc" depends="create">
<copy todir="${src.dir}" >
<fileset refid="src.id"></fileset>
</copy>
</target>
<!--3.编译源文件
ps:基于copy源文件操作的基础上
-->
<target name="complier" depends="copySrc">
<javac srcdir="${src.dir}" destdir="${classes.dir}"></javac>
</target>
<!--4.打包成jar
ps:为了直接运行jar包,在jar包中MANIFEST.MF增加:Main-Class:XXXX
-->
<target name="jar" depends="complier">
<jar destfile="${jar}" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
<attribute name="Build_By" value="${author}"/>
</manifest>
</jar>
</target>
<!--5.最终执行
方法1:基于build/classes中的编译文件进行执行
方法2:基于jar文件进行执行 ps:必须设置fork:true
-->
<target name="execute" depends="jar">
<echo>1.基于build/classes中的编译文件进行执行</echo>
<java classname="com.techbirds.HelloAnt" classpath="${classes.dir}">
<arg value="techbirds"/>
</java>
<echo>2.基于jar文件进行执行 ps:必须设置fork:true</echo>
<java jar="${jar}" fork="true">
<arg value="techbirds"/>
</java>
</target>
</project>
4.基于ant的junit3测试
极限编程=编码+单元测试 同步进行。
使用ant对源码文件进行单元测试的不步骤:
1.创建文件夹,创建成功以后的目录结构如下:
2.拷贝源文件
3.编译源文件
4.编译测试文件
5.利用ant执行单元测试文件类
ps:忽略了源码拷贝以及编译成jar文件的动作。
缺点:就是当添加另一个测试累时,很不方便。
<?xml version="1.0" encoding="UTF-8"?>
<project>
<property name="src.dir" location="src"></property>
<property name="test.src.dir" location="test"></property>
<property name="lib.dir" location="lib"></property>
<property name="build.dir" location="build"></property>
<property name="build.src.dir" location="${build.dir}/src"></property>
<property name="build.classes.dir" location="${build.dir}/classes"></property>
<property name="build.test.dir" location="${build.dir}/test"></property>
<property name="build.test.src.dir" location="${build.test.dir}/src"></property>
<property name="build.test.classes.dir" location="${build.test.dir}/classes"></property>
<!--测试报告存放位置-->
<property name="build.test.report.dir" location="${build.test.dir}/report"/>
<property name="run.test.class" value="com.techbirds.HelloWorldTest"></property>
<fileset id="build.src.files" dir="${src.dir}">
<include name="**/*.*"/>
</fileset>
<fileset id="test.src.files" dir="${test.src.dir}">
<include name="**/*.*"/>
</fileset>
<!--基于编译源文件所需要的依赖包
ps:lib包
-->
<path id="compile-path">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<!--基于编译测试文件所需要的依赖包
ps:lib包+编译完成的源文件class
-->
<path id="compile-test-path">
<path refid="compile-path"></path>
<!--增加编译好源文件的class类-->
<pathelement location="${build.classes.dir}"/>
</path>
<!--基于执行测试类所需要的依赖
ps:lib包+编译完成的源文件class+编译完成的测试类文件class
-->
<path id="run-test-path">
<path refid="compile-test-path"></path>
<pathelement location="${build.test.classes.dir}"/>
</path>
<target name="clean">
<echo>1.项目构建之前进行清除工作...</echo>
<delete dir="${build.dir}"></delete>
</target>
<target name="init" depends="clean">
<echo>2.项目构建的初始化工作...</echo>
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.src.dir}"/>
<mkdir dir="${build.classes.dir}"/>
<mkdir dir="${build.test.dir}"/>
<mkdir dir="${build.test.src.dir}"/>
<mkdir dir="${build.test.classes.dir}"/>
<mkdir dir="${build.test.report.dir}"/>
</target>
<target name="copySrc" depends="init">
<echo>3.拷贝源文件</echo>
<copy todir="${build.src.dir}">
<fileset refid="build.src.files"></fileset>
</copy>
<copy todir="${build.test.src.dir}">
<fileset refid="test.src.files"></fileset>
</copy>
</target>
<!--如果有依赖包的话,必须手动引入,否则会出错-->
<target name="compile" depends="copySrc">
<echo>4.编译源文件</echo>
<javac destdir="${build.classes.dir}" srcdir="${build.src.dir}" classpathref="compile-path"></javac>
<javac destdir="${build.test.classes.dir}" srcdir="${build.test.src.dir}" classpathref="compile-test-path"></javac>
</target>
<!--运行单元测试
1.单元测试的详细信息:printsummary="true"
2.执行出错不要往下执行:haltonfailure="true"
-->
<target name="run-test" depends="compile">
<echo>5.运行单元测试</echo>
<junit printsummary="true" haltonfailure="true">
<classpath refid="run-test-path"></classpath>
<test name="${run.test.class}"></test>
<formatter type="brief" usefile="false"/>
</junit>
</target>
</project>
解决方案:其他如上一个文件,忽略。。。
5.使用ant自动生成api使用文档+zip包
build.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project default="zip">
<property name="src.dir" location="src"></property>
<property name="build.dir" location="build"></property>
<property name="build.classes.dir" location="${build.dir}/classes"></property>
<property name="build.doc.dir" location="${build.dir}/doc/api"/>
<property name="build.zip.dir" location="${build.dir}/zip"></property>
<!--版本名称-->
<property name="version" value="release_0.1"></property>
<!--项目名称-->
<property name="project.name" value="user_${version}"></property>
<property name="zip.name" value="user.${version}.zip"></property>
<target name="clean">
<echo>1.项目构建之前进行清除工作...</echo>
<delete dir="${build.dir}"></delete>
</target>
<target name="init" depends="clean">
<echo>2.项目构建的初始化工作...</echo>
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes.dir}"/>
<mkdir dir="${build.doc.dir}"/>
<mkdir dir="${build.zip.dir}"/>
</target>
<!--生成doc,API帮助文档-->
<target name="doc" depends="init">
<javadoc sourcepath="${src.dir}" private="true" windowtitle="techbirds's doc"
use="true" packagenames="com.*" destdir="${build.doc.dir}"
charset="GBK" encoding="GBK" docencoding="GBK"
>
</javadoc>
</target>
<!--生成zip
ps:prefix:文件前缀,将文件集放置前缀位置
-->
<target name="zip" depends="doc">
<zip destfile="${build.zip.dir}/${zip.name}" duplicate="preserve">
<zipfileset dir="${build.doc.dir}" includes="**/*.*" prefix="${project.name}/doc/api"></zipfileset>
<zipfileset dir="${src.dir}" includes="**/*.*" prefix="${project.name}/src"></zipfileset>
</zip>
</target>
</project>
生成doc的功能还是很吊的。。。。
6.使用ant将5生成的zip包传送到指定的ftp上
由于需要搭建ftp服务器,这里使用win7自带的ftp功能,开启步骤:
1.控制面板-程序和功能->打开未启用的功能
2.在控制面板的管理工具->IIS管理器->添加ftp站点,配置按自己需要,忽略。。
在5的基础上:
<!--ftp上传文件
ps:ant环境添加apache-commons-net.jar
-->
<target name="ftp" depends="zip">
<ftp userid="XXXXX" password="XXXX" server="localhost" action="mkdir"
remotedir="user">
</ftp>
<ftp userid="XXXXX" password="XXXX" server="localhost" action="put"
remotedir="user">
<fileset dir="${build.zip.dir}" includes="*.zip"></fileset>
</ftp>
</target>