Apache Ant 使用详解(区别Maven打包)
Apache Ant 与 Maven 都可以作为项目打包工具(后端打包) 前后端分离的话,如果前端是react、Vue框架可以直接使用 webpack 打包
Ant with Ivy
Ant是第一个“现代”构建工具,在很多方面它有些像Make。2000年发布,在很短时间内成为Java项目上最流行的构建工具。它的学习曲线很缓,因此不需要什么特殊的准备就能上手。它基于过程式编程的idea。在最初的版本之后,逐渐具备了支持插件的功能。
主要的不足是用XML作为脚本编写格式。 XML,本质上是层次化的,并不能很好地贴合Ant过程化编程的初衷。Ant的另外一个问题是,除非是很小的项目,否则它的XML文件很快就大得无法管理。
后来,随着通过网络进行依赖管理成为必备功能,Ant采用了Apache Ivy。
Ant的主要优点在于对构建过程的控制上。
Maven
Maven发布于2004年。目的是解决码农使用Ant所带来的一些问题。
Maven仍旧使用XML作为编写构建配置的文件格式,但是,文件结构却有巨大的变化。Ant需要码农将执行task所需的全部命令都一一列出,然而Maven依靠约定(convention)并提供现成的可调用的目标(goal)。不仅如此,有可能最重要的一个补充是,Maven具备从网络上自动下载依赖的能力(Ant后来通过Ivy也具备了这个功能),这一点革命性地改变了我们开发软件的方式。
但是,Maven也有它的问题。依赖管理不能很好地处理相同库文件不同版本之间的冲突(Ivy在这方面更好一些)。XML作为配置文件的格式有严格的结构层次和标准,定制化目标(goal)很困难。因为Maven主要聚焦于依赖管理,实际上用Maven很难写出复杂、定制化的构建脚本,甚至不如Ant。
用XML写的配置文件会变得越来越大,越来越笨重。在大型项目中,它经常什么“特别的”事还没干就有几百行代码。
Maven的主要优点是生命周期。只要项目基于一定之规,它的整个生命周期都能够轻松搞定,代价是牺牲了灵活性。
在对DSL(Domain Specific Languages)的热情持续高涨之时,通常的想法是设计一套能够解决特定领域问题的语言。在构建这方面,DSL的一个成功案例就是Gradle。
Gradle
Gradle结合了前两者的优点,在此基础之上做了很多改进。它具有Ant的强大和灵活,又有Maven的生命周期管理且易于使用。最终结果就是一个工具在2012年华丽诞生并且很快地获得了广泛关注。例如,Google采用Gradle作为Android OS的默认构建工具。
Gradle不用XML,它使用基于Groovy的专门的DSL,从而使Gradle构建脚本变得比用Ant和Maven写的要简洁清晰。Gradle样板文件的代码很少,这是因为它的DSL被设计用于解决特定的问题:贯穿软件的生命周期,从编译,到静态检查,到测试,直到打包和部署。
它使用Apache Ivy来处理Jar包的依赖。
Gradle的成就可以概括为:约定好,灵活性也高。
Apache Ant 下载安装 :https://ant.apache.org/bindownload.cgi
配置环境变量: …………\apache-ant-1.9.2\bin
使用也简单: 写好项目的build.xml,后就可以用命令 ant xxx 来创建项目(注:xxx是配置文件中的target的name)
ant 命令
语法元素说明如下:
-help
显示描述ant 命令及其选项的帮助信息
-projecthelp
显示包含在构建文件中的、所有用户编写的帮助文档。即为各个中description 属性的文本,以及包含在元素中的任何文本。将有description 属性的目标列为主目标(Main target),没有此属性的目标则列为子目标(Subtarget)。
-version
要求ant 显示其版本信息,然后退出。
-quiet
抑制并非由构建文件中的echo 任务所产生的大多数消息。
-verbose
显示构建过程中每个操作的详细消息。此选项与-debug 选项只能选其一。
-debug
显示Ant 和任务开发人员已经标志为调试消息的消息。此选项与-verbose 只能选其一。
-emacs
对日志消息进行格式化,使它们能够很容易地由Emacs 的shell 模式(shellmode)所解析;也就是说,打印任务事件,但并不缩排,在其之前也没有[taskname]。
-logfile filename
将日志输出重定向到指定文件。
-logger classname
指定一个类来处理Ant 的日志记录。所指定的类必须实现了org.apache.tools.ant.BuildLogger 接口。
-listener classname
为Ant 声明一个监听类,并增加到其监听者列表中。在Ant与IDE或其他Java程序集成时,此选项非常有用。可以阅读第六章以了解有关监听者的更多信息。必须将所指定的监听类编写为可以处理Ant 的构建消息接发。
-buildfile filename
指定Ant 需要处理的构建文件。默认的构建文件为build.xml。
-Dproperty=value
在命令行上定义一个特性名-值对。
-find filename
指定Ant 应当处理的构建文件。与-buildfile 选项不同,如果所指定文件在当前目录中未找到,-find 就要求Ant 在其父目录中再进行搜索。这种搜索会继续在其祖先目录中进行,直至达到文件系统的根为止,在此如果文件还未找到,则构建失败。
-atuoproxy jdk1.5以上的可以使用代理设置
-nouserlib 运行ant时不使用用户lib中的jar包
-nice 设计主线程优先级
-logfile 使用指定的log日志
-noinput 不允许交互输入
-keep-going, -k 执行不依赖于所有目标
-propertyfile 加载所有属性配置文件 -d 属性文件优先
build.xml
<project default="all">
<property name="pro_a" value="a value" />
<property name="pro_b" value="b value" />
<path id="rt.path">
<pathelement location="${java.home}/jre/lib/rt.jar" />
</path>
<target name="all">
<javac srcdir=".">
<classpath refid="a.path" />
</javac>
</target>
</project>
注意:
● 所有构建文件都要有元素,而且至少有一个 元素。
● 对于 元素的default 属性并不一定需要默认值。
● 构建文件并不一定要被命名为build.xml。不过build.xml 是ant 要搜索的默认文件名。
● 每个构建文件只能有一个 元素。
在cmd窗口中进入到当前build.xml目录
复制代码代码如下:
ant
在当前目录下的build.xml运行Ant,执行缺省的target。
复制代码代码如下:
ant -buildfile build-test.xml
在当前目录下的build-test.xml运行Ant,执行缺省的target。
复制代码代码如下:
ant -buildfile build-test.xml clean
在当前目录下的build-test.xml运行Ant,执行一个叫做clean的target。
复制代码代码如下:
ant -buildfile build-test.xml -Dbuild=build/classes clean
在当前目录下的build-test.xml运行Ant,执行一个叫做clean的target,并设定build属性的值为build/classes。
ant编译打包、运行工程
<?xml version="1.0" encoding="UTF-8"?>
<!-- name是当前工程的名称,default是默认执行的任务,basedir是工作目录(.代表当前根目录) -->
<project name="HelloWorld" default="run" basedir=".">
<!-- property类似于程序中定义简单的变量 -->
<property name="src" value="src"/>
<property name="dest" value="classes"/>
<property name="hello_jar" value="helloWorld.jar"/>
<!--
target是一个事件、事情、任务, name是当前事情的名称,depends是依赖的上一件或是多件事情
如果所依赖的事情没有执行,ant会先运行依赖事情,然后再运行当前事情
-->
<!-- 初始化 -->
<target name="init">
<!-- 建立classes目录 -->
<mkdir dir="${dest}"/>
<mkdir dir="temp"/>
<mkdir dir="temp2"/>
</target>
<!-- 编译 -->
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${dest}"/>
<!-- 设置jvm内存
<javac srcdir="src" fork="true"/>
<javac srcdir="src" fork="true" executable="d:\sdk141\bin\javac"
memoryMaximumSize="128m"/>
-->
</target>
<!-- 建立jar包 -->
<target name="build" depends="compile">
<!--
<jar jarfile="${hello_jar}" basedir="${dest}"/>
创建一个名称是package.jar文件
<jar destfile="package.jar" basedir="classes"/>
-->
<jar destfile="${hello_jar}" basedir="classes">
<!-- 向jar包中的main文件中添加内容 -->
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-class" value="package.Main"/>
</manifest>
</jar>
<!-- 复制jar文件 todir="复制到目录"-->
<copy file="${hello_jar}" tofile="${dest}\temp.jar"/>
<copy todir="temp">
<!-- 不按照默认方式 defaultexcludes="" -->
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
</copy>
<copy todir="temp2">
<fileset dir="src">
<and>
<contains text="main"/>
<size value="1" when="more"/>
</and>
</fileset>
</copy>
<!-- 移动jar文件 -->
<move file="${dest}\temp.jar" tofile="temp\move-temp.jar"/>
<!-- 创建zip -->
<zip basedir="${basedir}\classes" zipfile="temp\output.zip"/>
<!-- 创建tgz -->
<gzip src="classes\**\*.class" zipfile="output.class.gz"/>
<!-- 解压zip -->
<unzip src="output.class.gz" dest="extractDir"/>
<!--替换input.txt内容中的old为new
<replace file="input.txt" token="old" value="new"/>
-->
</target>
<!-- 运行 -->
<target name="run" depends="build">
<java classname="com.hoo.test.HelloWorld" classpath="${hello_jar}"/>
</target>
<!-- 清除 -->
<target name="clean">
<!-- 删除生成的文件 -->
<delete dir="${dest}"/>
<delete file="${hello_jar}"/>
</target>
<tstamp>
<format property="OFFSET_TIME"
pattern="HH:mm:ss"
offset="10" unit="minute"/>
</tstamp>
<!-- 重新运行 -->
<target name="rerun" depends="clean,run">
<echo message="###${TSTAMP}#${TODAY}#${DSTAMP}###"/>
<aunt target="clean"/>
<aunt target="run"/>
</target>
</project>
ant不难,你用它就像是在docs控制台输入命令行一样,只不过ant是将命令行转换为xml的脚本信息,可以进行重复的运行。在一定情况下,提高了效率和重复的工作。