Ant的主要优点在于对构建过程的控制上。
在对DSL(Domain Specific Languages)的热情持续高涨之时,通常的想法是设计一套能够解决特定领域问题的语言。在构建这方面,DSL的一个成功案例就是Gradle。
我们写一段构建脚本来完成从编译、静态检查、单元测试到最终打Jar包的过程。我们分别使用三个框架(Ant,Maven和Gradle)来完成这件事情,比较一下语法。通过比较每一个任务的代码,我们能够对差异有一个更好的理解,并对选择构建工具做出一个周全的决策。
事有先后,如果你自己按照本文来学习样例,需要安装Ant,Ivy,Maven和Gradle,请根据相应工具的安装指导进行操作。你也可以不用自己跑样例,也统统不用安装,代码片段应该足够让你明白这些工具是如何工作的。
代码库 https://github.com/vfarcic/JavaBuildTools包含有Java代码(两个简单的类和测试代码),checkstyle配置文件和Ant,Ivy,Maven以及Gradle的配置文件。
先从Ant带着Ivy开始
Ivy的依赖需要在ivy.xml中指定。我们的例子很简单,只需要依赖JUnit和Hamcrest。
ivy.xml
<ivy-module version="2.0"> <info organisation="org.apache" module="java-build-tools"/> <dependencies> <dependency org="junit" name="junit" rev="4.11"/> <dependency org="org.hamcrest" name="hamcrest-all" rev="1.3"/> </dependencies> </ivy-module>
现在我们来创建Ant脚本,任务只是编译一个Jar文件。最终文件是下面的build.xml。
build.xml
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="java-build-tools" default="jar"> <property name="src.dir" value="src"/> <property name="build.dir" value="build"/> <property name="classes.dir" value="${build.dir}/classes"/> <property name="jar.dir" value="${build.dir}/jar"/> <property name="lib.dir" value="lib" /> <path id="lib.path.id"> <fileset dir="${lib.dir}" /> </path> <target name="resolve"> <ivy:retrieve /> </target> <target name="clean"> <delete dir="${build.dir}"/> </target> <target name="compile" depends="resolve"> <mkdir dir="${classes.dir}"/> <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="lib.path.id"/> </target> <target name="jar" depends="compile"> <mkdir dir="${jar.dir}"/> <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"/> </target> </project>首先,我们设置了几个属性,然后是一个接一个的task。我们用Ivy来处理依赖,清理,编译和打包,这是几乎所有的Java项目都会进行的task,配置有很多。
ant jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.technologyconversations</groupId> <artifactId>java-build-tools</artifactId> <packaging>jar</packaging> <version>1.0</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-all</artifactId> <version>1.3</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> </plugin> </plugins> </build> </project>通过执行下面的命令来运行Maven goal生成Jar文件。
mvn package主要的区别在于Maven不需要指定执行的操作。我们没有创建task,而是设置了一些参数(有哪些依赖,用哪些插件...). Maven推行使用约定并提供了开箱即用的goals。Ant和Maven的XML文件都会随时间而变大,为了说明这一点,我们加入CheckStyle,FindBugs和PMD插件来进行静态检查,三者是Java项目中使用很普遍的的工具。我们希望将所有静态检查的执行以及单元测试一起作为一个单独的target Verify。当然我们还应该指定自定义的checkstyle配置文件的路径并且确保错误时能够提示。更新后的Maven代码如下:
pom.xml
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>2.12.1</version> <executions> <execution> <configuration> <configLocation>config/checkstyle/checkstyle.xml</configLocation> <consoleOutput>true</consoleOutput> <failsOnError>true</failsOnError> </configuration> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> <version>2.5.4</version> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.1</version> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin>通过执行下面的命令来运行Maven goal,包括单元测试,静态检查,如CheckStyle,FindBugs和PMD。
mvn verify我们需要写很多XML来进行基本的常用的任务。在实际项目中有更多的依赖和task,Maven的pom.xml很容易就有成百上千行的配置。
apply plugin: 'java' apply plugin: 'checkstyle' apply plugin: 'findbugs' apply plugin: 'pmd' version = '1.0' repositories { mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' }Gradle不仅代码少了很多,对于熟悉的人来说,比Maven要更容易理解,而且它还包括很多Maven代码没有覆盖的有用的task。请执行下面的命令来得到Gradle在当前配置下能够支持的task列表。
gradle tasks --all
apply plugin: 'java'简单的这一行增加了20多个可用的任务.
原文链接:http://technologyconversations.com/2014/06/18/build-tools/