利用ant脚本 自动构建svn增量/全量 系统程序升级包
2014-10-20 23:38
357 查看
不会用ant打包、部署项目的工程师,不是一个好程序员(测试)
副标题:利用ant脚本自动构建svn增量/全量系统程序升级包首先请允许我这样说,作为开发或测试,你一定要具备这种本领。你可以手动打包、部署你的工程,但这不是最好的方法。最好的方式就是全自动化的方式。开发人员提交了代码后,可以自动构建、打包、部署到测试环境。测试通过后进入到模拟环境或是直接发布的生产环境,这个过程可以是全自动的。但这个自动化的方式有一些公司用到了,但也有很多公司还不知道,他们的攻城师天天在做反复、没有多大意义的、浪费生命的事情。当然这种方式一般针对做自己的产品,如电商、通信行业。而给其他公司或企业做项目的比较少利用这种方式,当然也可以利用这种方式,只是不能直接发布到客户的服务器而已。当然有些公司是专门有人做这部分事情的!
说了这么多也没有什么恶意,只是觉得这种方式可以大大提高效率,降低人力、物力、财力而已。勿喷,O(∩_∩)O哈哈~嘿嘿~
在部署项目或打包项目中,通常大家都是手动部署或打包的多。很多公司把这一任务交个了我们做开发的,其实这部分应该谁做呢?本质上应该是测试的来完成,但一些公司的测试不会做这个,慢慢的就变成了开发的事情。有些公司是人手比较少、不健全,所以一部分人自己承担了这个事情。在我们手动打包的时,其实这是一个重复的、没有技术含量的、耗费体力的活儿。一般步骤就是更新svn上代码、修改好相关的配置、编译class、发布到tomcat(web工程)、测试启动无误、手动打包。
而有一种比较简单快速的方式就是利用meven或ant来完成这些工作,只要我们编写好脚本后。给相关的工作人员去运行这部分脚本就可以完成打包,甚至是部署项目,这些都是soeasy~!我个人也比较赞成使用这种方式,比较简单、快速、重用性好,最难的可能编写build脚本,但这个脚本其实也是很简单的,它就想dos命令行,只不过它是用xml方式来完成命令行的而已。所以测试会写ant的build脚本这个也是应该的,如果你不会的话,还是建议你学习学习。反正是百益无一害的事情,何乐而不为呢!
一、基本流程
利用ant打包项目或打增量包的基本流程
值得一提的是jar包这个部分,这个步骤是为下面编译增量包做准备的。因为增量包导出的增量文件,它依赖于整个项目的其他代码,如果没有这些代码的支持是编译不通过。然而又不能直接通过diff得到增量的class,所以只能导出增量文件后,通过引用全部工程的代码的class再进行编译即可。
二、运行环境
1、安装jdk,不会自己上网查其他的
2、如果你还没有安装ant,那么你可以参考:
会介绍一下ant的安装和使用的方法。
3、这里需要用到svn的ant相关工具包、命令支持。你需要下载
4、因为某些项目使用到了泛型、annotation注解,使用javac有些代码是编译不通过的,所以这里使用了jdt的编译方式。参考:
需要用到
jdtCompilerAdapter.jar
org.eclipse.jdt.compiler.tool_1.0.1.v_793_R33x.jar
org.eclipse.jdt.core_3.3.3.v_793_R33x.jar
org.eclipse.jdt.debug.ui_3.2.102.v20071002_r332.jar
复制到ant_home/lib目录下,如果是利用eclipse运行脚本就需要把它加载到运行环境中。可以参考上面的:
三、编写ant的build脚本
1、首先看看ant工程的目录结构
简单介绍下目录结构:
src下面的ExportIncrementFiles.java是导出增量文件要用的,它在build命令increment中执行。它会读取diff比较后的文件中的内容,并导出文件
dest是checkout出来最新的svn的工程
dist是编译上面dest目录中的工程,也是svn全量war的工程目录和jar
increment_dest是增量工程,也就是上面的ExportIncrementFiles工具导出的工程
increment_dist是编译上面increment_dest的工程,也是增量包的工程目录
因为每个人的项目工程目录结构不一样,所以这个脚本并不会通用,我这里指针对自己的项目进行测试。
lib中是运行环境需要的jar库,其中主要的就是svnlib这个你可以去下载
svnant-1.3.1.zip以及JDT编译class的jar包,这个可以通过eclipse中的plugin中的jar包找到,可以参考:
increment.export.jar就是ExportIncrementFiles的class打成的jar包,这个是自己打的包,可以直接应用class也可以的,在increment命令引用,jar下载:
build.properties是当前build的配置文件
build.xml就是主要的ant脚本
选中部分是打的war包,这个就可以部署了
patch.txt就是svn的diff比较出的增量文件的目录路径列表
2、ExportIncrementFiles.java导出增量文件
packagecom.hoo.util;
importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.FileReader;
/**
*<b>function:</b>导出在增量的文件
*@authorhoojo
*@createDate2013-11-2下午10:00:01
*@fileExportIncrementFiles.java
*@packagecom.hoo.util
*@projectAntTest
*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code] *@emailhoojo_@126.com*@version1.0*/publicclassExportIncrementFiles{/***<b>function:</b>导出增量文件*@authorhoojo*@createDate2013-11-2下午10:15:43*@paramconfigPath增量文件路径配置目录*@parambaseDir基本路径目标位置*@paramdestDir增量文件保存位置*@throwsException*/privatestaticvoidexport(StringconfigPath,StringbaseDir,StringdestDir)throwsException{StringsrcFile=baseDir+configPath;StringdesFile=destDir+configPath;intlastIndex=desFile.lastIndexOf("/");StringdesPath=desFile.substring(0,lastIndex);FilesrcF=newFile(srcFile);if(srcF.exists()){//如果不存在这样的源文件,就不再拷贝,这个用来解决版本之间有删除文件的情况。FiledesF=newFile(desFile);FiledesP=newFile(desPath);if(!desP.exists()){desP.mkdirs();}System.out.println(srcFile);FileInputStreamfis=newFileInputStream(srcF);FileOutputStreamfos=newFileOutputStream(desF);byte[]buf=newbyte[1024];intlen=0;while((len=fis.read(buf))!=-1){fos.write(buf,0,len);}fos.flush();fos.close();fis.close();}}/***<b>function:</b>主函数执行导出增量包任务*@authorhoojo*@createDate2013-11-2下午10:00:01*@paramargs参数1增量包导出文件路径,参数2要导出的文件的所在目标位置,参数3增量包导出保存的位置路径*/publicstaticvoidmain(String[]args){if(args.length>0){if(args.length==1&&"help".equals(args[0])){System.out.println("args[0]isExportIncrementFilescontentpath");System.out.println("args[1]isExportIncrementFilestargetpath");System.out.println("args[2]isIncrementFilesExportloaction");}else{StringconfigPath=args[0];StringbaseDir=args[1];StringdestDir=args[2];try{BufferedReaderbr=newBufferedReader(newFileReader(configPath));Strings=null;while((s=br.readLine())!=null){s=s.trim();//去掉路径前面的空格Stringstr=destDir+s;if(!destDir.equals(str)){//过滤空行export(s,baseDir,destDir);}}br.close();}catch(Exceptione){e.printStackTrace();}}}}}
main函数参数看注释,主要就是读取patch.txt增量文件路径,导出文件到指定目录的。
3、build脚本<?xmlversion="1.0"encoding="UTF-8"?><!--createDate2013-10-28--><!--authorhoojo&http://blog.csdn.net/IBM_hoojo& http://hoojo.cnblogs.com--> <projectdefault="checkout"basedir="."><propertyfile="build.properties"/><!--svn比较项目最新路径--><propertyname="svn.url"value="${svn._url}"/><!--svn备份路径--><propertyname="bak.svn.url"value="${bak.svn._url}"/><propertyname="svn.username"value="${svn.username}"/><propertyname="svn.password"value="${svn.password}"/><!--项目名称--><propertyname="webapp"value="${webapp.name}"/><!--目标项目的Web名称(WEB-INF上一级的目录名称)--><propertyname="webroot"value="${web.root}"/><!--svn改动文件列表信息--><propertyname="compare.path.file"value="${increment.file}"/><!--svn导出/切出文件存放目录--><propertyname="dest.path"location="dest/${webapp}"/><!--svn导出/切出文件编译后存放目录--><propertyname="dist.path"location="dist/${webapp}"/><!--svn增量文件保存目录--><propertyname="increment.dest.path"location="increment_dest/${webapp}"/><!--svn增量文件编译后保存目录--><propertyname="increment.dist.path"location="increment_dist/${webapp}"/><!--利用jdt编译class解决泛型不能转换的问题需要将jdtCompilerAdapter.jarorg.eclipse.jdt.compiler.tool_1.0.1.v_793_R33x.jarorg.eclipse.jdt.core_3.3.3.v_793_R33x.jarorg.eclipse.jdt.debug.ui_3.2.102.v20071002_r332.jar复制到ant_home/lib目录下<propertyname="build.compiler"value="org.eclipse.jdt.core.JDTCompilerAdapter"/>--><pathid="svnant.classpath"><filesetdir="${basedir}"><includename="**/*.jar"/></fileset></path><pathid="buildpath"><filesetdir="${dest.path}"><includename="**/lib/*.jar"/></fileset><filesetdir="C:/ProgramFiles/Java/jdk1.6.0_13"><includename="**/*.jar"/></fileset></path><typedefresource="org/tigris/subversion/svnant/svnantlib.xml"classpathref="svnant.classpath"/><svnSettingid="svn.settings"javahl="false"svnkit="true"username="${svn.username}"password="${svn.password}"failonerror="true"/><targetname="init"description="initcleandirs"><echomessage="${svn.username}"/><echomessage="${svn.password}"/><echomessage="${webapp}"/><echomessage="${webroot}"/><echomessage="${compare.path.file}"/><deletedir="${dest.path}"failonerror="false"deleteonexit="true"excludes="**/lib"/><deletedir="${dist.path}"failonerror="false"deleteonexit="true"excludes="**/lib"/><deletefile="${compare.path.file}"failonerror="false"/><deletedir="${increment.dest.path}"failonerror="false"deleteonexit="true"/><deletedir="${increment.dist.path}"failonerror="false"deleteonexit="true"/></target><!--thatistotestisvnantisavailable//--><targetname="tool-available"depends="init"><echomessage="runtasktestsvnantisavailable"></echo><availableresource="org/tigris/subversion/svnant/svnantlib.xml"classpathref="svnant.classpath"property="available.svnant"/><echomessage="SVN-ANTisavailable=${available.svnant}"></echo></target><!--比较差异增量文件--><targetname="diff"description="deff/compareproject"><svnrefid="svn.settings"><diffSummarizeoldUrl="${bak.svn.url}"newUrl="${svn.url}"outFile="${compare.path.file}"recurse="true"/></svn></target><!--下载切成导出服务器上最新代码--><targetname="checkout"depends="tool-available"description="checkout/exportprojectcode${svn.url}"><echomessage="checkout/exportprojectcode${svn.url}"></echo><svnrefid="svn.settings"><exportsrcUrl="${svn.url}"destPath="${dest.path}"revision="HEAD"force="true"/></svn></target><!--javac编译--><targetname="compile"><buildnumber/><echo>compile${dest.path}......</echo><deletedir="${dist.path}"failonerror="false"deleteonexit="true"excludes="**/lib"/><mkdirdir="${dist.path}/classes"/><javacnowarn="true"debug="${javac.debug}"debuglevel="${javac.debuglevel}"destdir="${dist.path}/classes"source="${javac.source}"target="${javac.target}"encoding="utf-8"fork="true"memoryMaximumSize="512m"includeantruntime="false"><srcpath="${dest.path}/src"/><!--<compilerargvalue="-Xlint:unchecked"/><compilerargvalue="-Xlint:deprecation"/><compilerargvalue="-Xlint"/>--><classpathrefid="buildpath"/><classpathrefid="svnant.classpath"/></javac></target><!--利用JDT编译--><targetname="compile_jdt"><buildnumber/><echo>compile${dest_path}......</echo><deletedir="${dist_path}"failonerror="false"deleteonexit="true"excludes="**/lib"/><mkdirdir="${dist_path}/classes"/><javaccompiler="org.eclipse.jdt.core.JDTCompilerAdapter"nowarn="true"debug="${javac.debug}"debuglevel="${javac.debuglevel}"destdir="${dist_path}/classes"source="${javac.source}"target="${javac.target}"encoding="utf-8"fork="true"memoryMaximumSize="512m"includeantruntime="false"><srcpath="${dest_path}/src"/><classpathrefid="buildpath"/><classpathrefid="svnant.classpath"/></javac></target><!--利用JDT编译SVN最新项目--><targetname="compile_svn"><!--回调任务--><antcalltarget="compile_jdt"><paramname="dest_path"value="${dest.path}"/><paramname="dist_path"value="${dist.path}"/></antcall></target><!--将全部项目的class建立jar包--><targetname="jar"depends="compile_svn"><jardestfile="${basedir}/lib/${webapp}.jar"level="9"compress="true"encoding="utf-8"basedir="${dist.path}/classes"><manifest><attributename="Implementation-Version"value="Version:2.2"/></manifest></jar></target><!--导出增量文件--><targetname="increment"depends="diff"><javaclassname="com.hoo.util.ExportIncrementFiles"classpath="${basedir}/lib/increment.export.jar"fork="true"><argvalue="${compare.path.file}"/><argvalue="${dest.path}/"/><argvalue="${increment.dest.path}/"/></java></target><!--利用JDT编译增量文件--><targetname="compile_increment"><antcalltarget="compile_jdt"><paramname="dest_path"value="${increment.dest.path}"/><paramname="dist_path"value="${increment.dist.path}"/></antcall></target><!--全部打包--><targetname="war"><echo>createwarfile.......</echo><copytodir="${dist_path}"failonerror="false"><filesetdir="${dest_path}/${webroot}"includes="**"/></copy><movetodir="${dist_path}/WEB-INF/classes"failonerror="false"><filesetdir="${dist_path}/classes"/></move><copytodir="${dist_path}/WEB-INF/classes"failonerror="false"><filesetdir="${dest_path}/src/main/"includes="**/*.xml,**/*.properties,**/*.xsd"/><filesetdir="${dest_path}/src/test/"includes="**/*.xml,**/*.properties,**/*.xsd"/><filesetdir="${dest_path}/src/resource/"includes="**/*.xml,**/*.properties,**/*.xsd"/></copy><!--得到当前日期--><tstamp><formatproperty="DSTAMP"pattern="yyyyMMdd"locale="zh"/><formatproperty="TSTAMP"pattern="HHmmss"locale="zh"/></tstamp><wardestfile="${basedir}/${webapp}_${DSTAMP}_${TSTAMP}.war"basedir="${dist_path}"webxml="${dist_path}/WEB-INF/web.xml"/></target><!--全部打包--><targetname="war_svn"><antcalltarget="war"><paramname="dest_path"value="${dest.path}"/><paramname="dist_path"value="${dist.path}"/></antcall></target><!--全部打包--><targetname="war_increment"><copytodir="${increment.dist.path}/WEB-INF"file="${dest.path}/${webroot}/WEB-INF/web.xml"/><antcalltarget="war"><paramname="dest_path"value="${increment.dest.path}"/><paramname="dist_path"value="${increment.dist.path}"/></antcall></target><!--svn全量包--><targetname="svn_war"depends="checkout,compile_svn,war_svn"/><!--增量包--><targetname="increment_war"depends="checkout,increment,jar,compile_increment,war_increment"/></project>
4、build的配置文件内容#Mon,04Nov201311:18:12+0800svn._url=http://172.31.100.100/svn/iMVS_DataComm2bak.svn._url=http://172.31.100.100/svn/iMVS_DataCommsvn.username=hoojosvn.password=mypasswebapp.name=iMVS_DataCommweb.root=WebRootincrement.file=patch.txtjavac.debuglevel=source,lines,varsjavac.target=1.6javac.source=1.6javac.debug=true
运行svn_war任务可以打全部的包,也就是svn最新地址的项目工程包。
运行increment_war任务可以打增量包,也会形成一个war文件。
如果你需要发布到tomcat目录,可以写一个任务copy相关war包到tomcat的webapps的目录下,这个很简单~如果你需要调用tomcat的相关任务或命令,你需要在build脚本中加入<targetname="_def_tomcat_tasks"><!--tasks:deploy,undeploy,reload,stop,start,list,roles,resources--><taskdefname="deploy"classname="org.apache.catalina.ant.DeployTask"/><taskdefname="list"classname="org.apache.catalina.ant.ListTask"/><taskdefname="reload"classname="org.apache.catalina.ant.ReloadTask"/><taskdefname="resources"classname="org.apache.catalina.ant.ResourcesTask"/><taskdefname="roles"classname="org.apache.catalina.ant.RolesTask"/><taskdefname="start"classname="org.apache.catalina.ant.StartTask"/><taskdefname="stop"classname="org.apache.catalina.ant.StopTask"/><taskdefname="undeploy"classname="org.apache.catalina.ant.UndeployTask"/></target>
关于这些命令使用方法有兴趣的可以自己研究研究。
四、总结
整个流程稍微有点复杂,只要思路清晰这个build脚本还是很容易编写的。前提是你要懂得Java发布、编译、部署的流程,很多人用eclipse或MyEclipse来发布工程,好像很简单。其实在工具背后也是使用这些脚本完成的,知道在用户目录下有一个.m2的目录么,这个就是eclipse工具的meven的缓存和配置的内容。所以当我们不使用这些ide的情况下,你怎么编译、部署你的项目呢~!这篇文章只是一个抛砖引玉的效果,希望能给大家一个启示。在这之前,我在网上搜集了些资料也没有找到打增量包的比较好的方法,全都是手动方式。
同时,在一些自动集成或持续集成的智能工具中,也大量的使用到了这方面的技术。如果你想更智能的完成这个项目的发布、部署的话,这里只是其中的第一步。有兴趣的朋友可以研究下Continuousintegration或Hudson等相关自动化集成技术应用。
本文转自:/article/4791948.html
相关文章推荐
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包【转】
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 副标题:利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn增量/全量 系统程序升级包
- 利用ant脚本 自动构建svn全量/增量/减量 项目升级包
- SVN全量备份和增量备份脚本
- Eclipse/MyEclipse设置在保存文件时自动调用Ant脚本执行一些构建操作
- SVN自动全备份及增量备份脚本,包含文件压缩,可加入window 任务
- 利用Ant实现项目自动构建测试备份并发布到项目web
- SVN自动全备份及增量备份脚本,包含文件压缩,可加入window 任务
- ANT发布SVN WEB项目到TOMCAT以及利用post-commit自动提交编译更新
- ant+svn+tomcat实现自动构建