[Gradle] 在 Eclipse 下利用 gradle 构建系统

转载自:http://www.ibm.com/developerworks/cn/opensource/os-cn-gradle/html

构建系统时候经常要用到 Ant, Maven 等工具,对于初学者来讲,它们仍是过于复杂,上手仍是须要时间的。本文将向读者介绍一种全新的构建项目的方式 gradle,它简单、上手快,能大大节省项目的时间和成本。java

在 eclipse 下利用 gradle 构建系统

基本开发环境linux

  • 操做系统:本教程使用的为 Windows Vista Enterprise, 若是您的系统是 Linux 的,请选择下载对应版本的其余工具,包括开发工具、Java EE 服务器、Apache Ant、SoapUI。
  • 开发工具:Eclipse IDE for SOA Developers 版本,请到 http://www.eclipse.org/downloads/ 网站下载,固然任何版本的 eclipse 都是能够的。
  • Java EE 服务器:Apache-Tomcat-6.0.18,能够到 http://tomcat.apache.org/download-60.cgi 下载,使用 5.0 以上的任何版本均可以的,固然,您也可使用 Jboss 等其余 Java EE 服务器。
  • Jdk:到 http://java.sun.com 下载 1.5.0_17 版本,下载后安装便可。

Ant,Maven,Gradle 简单比较

Ant 是咱们过去构建系统基本都会用到的,xml 脚本文件中包括若干 task 任务,任务之间能够互相依赖,对于一个大的项目来讲,这些 xml 文件维护起来的确不是一件容易的事情,还有那些项目依赖的而没有版本号的 jar 包,有时真的让人头疼,后来 Maven 出现了,基于中央仓库的编译相对于 Ant 来讲的确是好了不少,可是,是否是 Ant,Maven 就是咱们构建项目的惟一选择呢?呵呵,固然不了,利用 Gradle 来构建系统我认为将成为 java 构建项目的最佳选择,简单,快速,对初学者无苛刻要求,能够说是拿来就会用,并且咱们不再用看那些冗长而复杂的 xml 文件了,由于 Gradle 是基于 Groovy 语言的,Groovy 你们应该很熟悉吧,是基于 Java Virtual Machine 的敏捷开发语言,它结合了 Python、Ruby 和 Smalltalk 的许多强大的特性,若是你是一个 Ant 的彻底支持者,也没有问题,由于 Gradle 能够很平滑的来调用 Ant 文件的,我这样说你可能不接受 Gradle,下面咱们就会经过一个个具体实例来说解 Ant,Maven,Gradle 构建项目的过程,经过例子咱们能很容易明白它们的差别。Let ’ s go。web

用 Ant 来构建简单系统

新建一个 Java project, 命名为 ant_projectapache

图 1. 新建 ant_project 项目
图 1. 新建 ant_project 项目

而后新建一个 HelloWorld 类,咱们下面就是将这个项目经过 Ant 来编译,打包,类的代码列表如清单 1 所示:api

清单 1. HelloWorld 类
package org.ant.test; 

 public class HelloWorld { 
     public String sayHello(String name){ 
         return "Hello "+name; 
     } 
 }

 

而后再新建一个 build 文件,命名为 build.xml, 内容如清单 3 所示:tomcat

清单 2. build.xml
 <?xml version="1.0" encoding="UTF-8"?> 
 <project name="project" default="default"> 
    <target name="default" depends="depends" description="description"> 
        <javac srcdir="src" destdir="bin" includes="org/**"></javac> 
         <jar basedir="bin" destfile="dist/ant_project.jar"></jar> 
         <war destfile="dist/ant_project.war" webxml="WEB-INF/web.xml"> 
             <classes dir="bin"></classes> 
         </war> 
    </target> 
    <!-- - - - - - - - - - - - - - - - - - 
          target: depends                      
         - - - - - - - - - - - - - - - - - --> 
    <target name="depends"> 
    </target> 
 </project>

 

熟悉 ant 的同窗们对于上面的脚本应该很容易看明白,这里就不详细解释了,主要功能就是把这个工程编译而后打成 jar 和 war 包。 到目前为止 ant_project 的目录结构如图 2 所示:服务器

图 2. ant_project 工程目录结构
图 2. ant_project 工程目录结构

运行 ant 脚本。app

 E:\gdcc\tools\apache-ant-1.6.5\bin\ant -f  E:\ws_IBM\ant_project\build.xml 
 
注:ant 放在了 E:\gdcc\tools\apache-ant-1.6.5 目录下。
执行结果以下:
 Buildfile: E:\ws_IBM\ant_project\build.xml 
 depends: 
 default: 
    [javac] Compiling 1 source file to E:\ws_IBM\ant_project\bin 
      [jar] Building jar: E:\ws_IBM\ant_project\dist\ant_project.jar 
      [war] Building war: E:\ws_IBM\ant_project\dist\ant_project.war 
 BUILD SUCCESSFUL 
 Total time: 859 milliseconds

 

这是个很是简单的工程,咱们将他打成了 jar,war 包,所须要的 build 文件大约在 10 行左右,下面咱们再看看用 Gradle 的状况。eclipse

用 Gradle 来构建简单系统

准备环境:

  1. 下载 gradle-0.9-preview-1 从 http://dist.codehaus.org/gradle/?ref=darwinports.com网站上选择一个版本,而后解压到指定目录,将 Gradle 的 bin 目录添加到 Path 变量中。
  2. 使用 cmd 命令,而后敲入 gradle – version,如出现如下信息,表示环境配置成功。
 C:\Documents and Settings\suchu>gradle -version 
 Gradle 0.9-preview-1 
 Gradle buildtime: Monday, March 29, 2010 4:51:14 PM CEST 
 Groovy: 1.7.1 
 Ant: Apache Ant version 1.8.0 compiled on February 1 2010 
 Ivy: 2.1.0 
 Java: 1.6.0_12 
 JVM: 11.2-b01 
 JVM Vendor: Sun Microsystems Inc.

 

注:以上信息根据不一样版本的 Gradle 或者不一样的环境也许不一样,但都是正确的。

Gradle 经常使用的使用方法介绍

新建一个 Java project, 命名为 gradle_project

图 3. 新建 gradle_project 项目
图 3. 新建 gradle_project 项目

而后新建一个 java bean 名为 HelloWorld 内容和上面的同样,能够参考 ant_project。 为了实现编译,打包功能,咱们须要新建一个名为 build.gradle 的文件。 文件内容见清单 3 所示:

清单 3. build.gradle 内容
apply plugin: 'java'

 

是否是很惊讶,的确,真的就只要这么短短的一行,而它的功能倒是至关的强大的,能编译,打成 jar 包,运行测试脚本等。 到目前为止,项目的结构如图 4 所示:

图 4. gradle_project 项目结构图
图 4. gradle_project 项目结构图

这里须要注意一点的是,项目包的结构最好是按照 Gradle 指望的来创建,固然也能够经过配置来改变。 下面咱们来运行下 build.gradle 文件。 运行 cmd 命令,进入 gradle_project 项目路径下,而后运行 gradle build 命令,命令显示信息如清单 5 所示。

清单 5. build.gradle 运行显示信息
 E:\ws_IBM\gradle_project>gradle build 
 :compileJava 
 :processResources 
 :classes 
 :jar 
 :assemble 
 :compileTestJava 
 :processTestResources 
 :testClasses 
 :test 
 :check 
 :build 

 BUILD SUCCESSFUL 

 Total time: 5.125 secs

 

咱们再看下生成物,这个命令首先在 gradle_project 下新建了 build 目录,build 目录包含 classes, dependency-cache, libs,tmp 四个目录,libs 下包含 jar 包,jar 包包含 main 下的全部 java 文件和和资源文件。 一个简单的例子到这里就演示完了,怎么样是否是脚本很简洁,用起来很简单,产生想继续学习的兴趣了吧,别急,下面咱们会继续来探究 Gradle 的神奇之处。

下面咱们来介绍几个经常使用的命令,clean,这个命令是将刚才产生的 build 目录删除掉; Assemble,这个命令是编译 java 文件可是不运行检查代码质量等的命令,运行时显示的信息如清单 6 所示:

清单 6. assemble 命令显示的信息
E:\ws_IBM\gradle_project>gradle assemble 
 :compileJava 
 :processResources UP-TO-DATE 
 :classes 
 :jar 
 :assemble 

 BUILD SUCCESSFUL

 

和清单 5 比较下,他们的区别应该很容易看出来,那么咱们怎么样来运行检查代码质量的命令而不须要打成 jar 包之类的额外工做呢,check 命令正好知足你的要求,此命令就是编译 java 文件并运行那些相似 Checkstyle,PMD 等外部插件命令来检查咱们本身的源代码。Check 命令运行显示的信息如清单 7 所示:

清单 7. check 命令运行时信息
 E:\ws_IBM\gradle_project>gradle check 
 :compileJava UP-TO-DATE 
 :processResources UP-TO-DATE 
 :classes UP-TO-DATE 
 :compileTestJava UP-TO-DATE 
 :processTestResources UP-TO-DATE 
 :testClasses UP-TO-DATE 
 :test UP-TO-DATE 
 :check UP-TO-DATE 

 BUILD SUCCESSFUL

 

这里须要说明一点的是 Gradle 是增量式编译的,只编译那些有变更的 java 类或资源文件的,如 UP-TO-DATE 表示是有更新的。 如今 javadoc 愈来愈受到人们的重视,尤为对于那些复杂的须要接口调用的的项目,javadoc 的地位就更加突出了,若是咱们使用 Ant 须要在 build 文件中增长清单 8 的片断。

清单 8. 利用 Ant 生成 javadoc
     <target name="javadoc"> 
       <!-- destdir 是 javadoc 生成的目录位置 --> 
      <javadoc destdir="${distDir}" encoding="UTF-8" docencoding="UTF-8"> 
          <!-- dir 是你的源代码位置,记住是 java 文件的位置而不是 class 文件的位置,
                       第一次用这个命令容易忽略这点 切记 --> 
                <packageset dir="${srcDir}"> 
           <!-- exclude 是去掉那些不想生成 javadoc 的类文件 --> 
                             <exclude name="${excludeClasses}" /> 
                                   </packageset> 
                           </javadoc> 
        </target>

 

而后咱们用 ant javadoc 命令来运行,便可生成 javadoc。那么咱们 利用 Gradle 是怎样来生成 javadoc 的呢,都须要作那些额外的工做呢? build.gradle 文件是否须要修改呢?咱们的回答是,不用,什么都不用修改,什么都不用作,只需利用 gradle javadoc 命令,便可生成咱们指望的 javadoc。 一般咱们新建一个项目,.classpath 文件的内容如清单 9 所示:

清单 9. .classpath 文件内容
<?xml version="1.0" encoding="UTF-8"?> 
 <classpath> 
     <classpathentry kind="src" path="src"/> 
     <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER
        /org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_12"/> 
     <classpathentry kind="output" path="bin"/> 
 </classpath>

 

经过上面的知识咱们知道,Gradle 指望的目录结构和自动生成的是有些差异的,好比源码路径,编译后的文件放置目录等,那么咱们能不能经过 Gradle 命令来统一一下呢,使原项目结构与 Gradle 指望的一致,以避免开发者将代码放置到了错误的目录结构下,那样 Gradle 是无论理它们的。下面咱们就经过一个简单的方法来实现上面的需求,首先咱们来简单修改下 build.gradle 文件,添加 apply plugin: 'eclipse'这么一行,而后咱们使用命令 gradle eclipse 便可。.classpath 文件的变化如清单 9 所示。

清单 9. 修改后的 .classpath 文件内容
 <?xml version="1.0" encoding="UTF-8"?> 
 <classpath> 
  <classpathentry kind="src" path="src/main/java"/> 
  <classpathentry kind="output" path="build/classes/main"/> 
  <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> 
 </classpath>

 

War 包是咱们常常要用到的,上面咱们利用 Ant 脚本生成过 war 包,那么 Gradle 又是怎样来生成 war 包的呢?通过上面的学习或许你已经猜出来了,须要增长一个 plugin,彻底正确,只须要将 apply plugin: 'war' 这一行加入到 build.gradle 文件中,而后运行 gradle War 命令便可,简单的简直要命,是否是,呵呵!

如何在老项目上使用 Gradle

咱们上面讲过,Gradle 对其所能控制的目录结构是有必定的要求的,那么若是咱们的项目已经开始很长时间了,如今的项目结构不知足 Gradle 的要求,那么咱们还能不能利用 Gradle 呢?答案固然是确定的,下面咱们就介绍怎样在老项目上使用 Gradle,方法很简单,固然若是过于复杂咱们也不必再这里介绍它了,直接使用 Ant 就行了。首先咱们须要在 build.gradle 文件中增长如清单 10 所示的内容。

清单 10. 匹配老项目的结构
 sourceSets { 
     main { 
         java.srcDir "$projectDir/src"
     } 
 }

 

而后咱们就可使用 Gradle 提供的全部命令和方法了。

如何加入项目所依赖的 jar 包

你们都知道,一个项目在编译过程当中要依赖不少 jar 包的,在 Ant 中咱们经过添加 classpath 来实现的,如清单 11 所示。

清单 11. ant 中添加依赖的 jar 包
 <path id="j2ee"> 
         <pathelement location="${servlet.jar}" /> 
         <pathelement location="${jsp-api.jar}" /> 
         <pathelement location="${ejb.jar}" /> 
         <pathelement location="${jms.jar}" /> 
 </path> 
 <javac destdir="${build.classes}" srcdir="${src.dir}" debug="${javac.debug}" 
                 deprecation="${javac.deprecation}"> 
             <include name=" "/> 
             <classpath refid="j2ee"/> 
 </javac>

 

那么 Gradle 又是怎样来作的呢?经过上面的知识的学习,你是否有一个大概的思路呢?假如咱们如今有一个 java 类叫 HelloWorldTest,这个类中引用了 junit 这个 jar 包中的类,这时候咱们用 Gradle 要怎样来编译这个类呢? 首先咱们新建一个目录叫 libs,这个目录就是放置项目所依赖的全部 jar 包,固然包括 HelloWorldTest 类所依赖的 junit-4.4.jar 包,而后咱们要修改下 build.gradle 文件,增长内容见清单 12。

清单 12. 工程所依赖 jar 包添加方法
repositories { 
     flatDir(dirs: "$projectDir/libs") 
 } 
 dependencies { 
     compile ':junit:4.4'
 }

 

注:repositories 至关一个存储 jar 包的仓库,咱们能够指定本地的依赖 jar 包,也能够利用 Maven 所指定的仓库,如 mavenCentral(); 经过 dependencies 来包含全部真正要依赖的 jar 包,格式为 goup:name:version,':junit:4.4:' 就是表示 dirs 路径下的 junit-4.4.jar 这个包。

如何实现 copy 工做

Copy 是咱们常常要用到的一个命令,java 类的 copy,资源文件的 copy 等等。若是是 Ant 咱们会在 build.xml 文件中加入清单 13 中的内容。

清单 13. Ant 中的 copy 任务
复制单个文件到另外一个文件
  <copy file="myfile.txt" tofile="mycopy.txt"/> 
复制单个文件到一个目录
  <copy file="myfile.txt" todir="../some/other/dir"/> 
复制一个目录到另外一个目录
  <copy todir="../new/dir"> 
    <fileset dir="src_dir"/> 
  </copy> 
复制一部分文件到一个目录下
  <copy todir="../dest/dir"> 
    <fileset dir="src_dir"> 
      <exclude name="**/*.java"/> 
    </fileset> 
  </copy> 
  <copy todir="../dest/dir"> 
    <fileset dir="src_dir" excludes="**/*.java"/> 
  </copy>

 

咱们知道 copy 任务中有不少属性,这里咱们就不一一列出了,咱们仍是主要看下 Gradle 是如何来实现这些功能的。

使用 Gradle 实现目录之间 copy 文件任务

咱们只须要在 build.gradle 文件中加入清单 14 中的内容。

清单 14. gradle 中实现目录间复制文件
 task copyOne(type: Copy) { 
     from 'src/main/test'
     into 'build/anotherDirectory'
 }

 

注:把 test 目录下的全部文件复制到 anotherDirectory 目录下。 而后咱们利用命令 E:\ws_IBM\gradle_project>gradle copyOne 来执行便可。

对 copy 文件的过滤

有时候一个目录下的文件数目不少,而咱们只想复制某一部分文件,好比只复制 java 文件或资源文件等,这时候咱们就要用到 copy 任务的 include 属性,这一点和 Ant 是同样的。好比只复制 java 文件到某一指定目录,实现这个需求咱们要在 build.gradle 文件中增长清单 15 的内容。

清单 15. copy java 文件到指定目录
 task copyTwo(type: Copy) { 
     from 'src/main/test'
     into 'build/anotherDirectory'
     include '**/*.java'
 }

 

若是咱们只想排除一些文件,不想把这一类文件 copy 过去,这时候咱们要用到 exclude 属性,好比咱们不想把 java 文件复制到指定目录中,那么咱们只须要将上面清单 15 中的 include 替换成 exclude 便可。

发布 jar 文件

作项目时常常会遇到一个 project 中的类依赖另外一个 project 中类的状况,若是用 Ant,咱们会这样作,首先将被依赖的类文件打成 jar 包,而后利用 copy 命令将这个 jar 包复制到指定目录下,咱们能够想象到要向 build.xml 添加好多行代码,这里咱们就不一一列出了,不会的同窗们能够参考上面的知识。下面咱们看下 Gradle 是怎样来完成这一需求的,Gradle 不但能够讲 jar 包发布到本地的指定目录中,并且还能够发布到远程目录中,咱们看下清单 16 的内容。

清单 16. 发布 jar 包到本地目录
publishJarFile { 
     repositories { 
         flatDir(dirs: file('jarsDerectory')) 
     } 
 }

 

而后咱们利用 gradle publishJarFile 命令便可。 注:清单 16 是将工程下的 java 类文件所有打成 jar 包,而后放到工程目录下的 jarsDerectory 子目录中。

Maven 对于 jar 包的仓库管理方法给咱们提供了不少方便,Gradle 彻底能够利用 Maven 的这一优势的,咱们在上面已经讲过了如何来使用,那么咱们又是怎么来作到将项目所须要的 jar 包更新到仓库中呢?具体解决方法见清单 17。

清单 17. 发布 jar 文件到 Maven 的仓库中
apply plugin: 'maven'
 publishToMaven { 
 repositories.mavenDeployer { 
 repository(url: "file://localhost/tmp/myRepo/") 
 } 
 }

 

Gradle 在多个工程中的应用

作项目时候,常常会碰到多个工程的状况,最一般的状况咱们也分为服务器端和客户端两部分,这种状况咱们过去用 Ant 时候会在每一个工程下面都创建个 build.xml 文件或者创建一个 build.xml 文件,而后在这个 build.xml 文件中创建不一样工程的 target,将将被引用的工程打成 jar 包来供其余工程引用,那么 Gradle 是怎样来完成这样的需求的呢?下面咱们举个具体的例子来详细演示下。首先咱们新建一个主工程命名为 gradle_multiProject, 而后在主工程下在新建一个子工程命名为 sub_projectOne, 在两个工程下面都有一个各自独立的 src 而且符合 Gradle 要求的目录结构,在每一个工程下面都建个类命名为 HelloWorld,类内容同清单 1. 而后咱们新建个 settings.gradle 文件,内容见清单 18。

清单 18. settings.gradle 文件内容
include "sub_projectone"

 

而后在新建一个咱们熟悉的 build.gradle 文件,文件内容见清单 19。

清单 19. 主工程目录下 build.gradle 文件内容
 Closure printProjectName = { task -> println "I'm $task.project.name" } 
 task hello << printProjectName 
 project(':sub_projectone') { 
     task hello << printProjectName 
 }

 

而后咱们使用命令 gradle – q hello 运行一下,运行结果如清单 20 所示。

清单 20. 命令运行结果
 E:\ws_IBM\gradle_multiProject>gradle -q hello 
 I'm gradle_multiProject 
 I'm sub_projectone

 

咱们会发现,这个命令将主工程和子工程的名字都打印出来了,为何会这样呢?我想 你必定猜对了,由于咱们在 build.gradle 文件中使用了 project() 方法,方法内传入的是子工程的名称,若是咱们子工程不止一个,那么咱们又该怎样来调用呢?这时候咱们只须要调用另外一个方法 allprojects 便可,注意 allprojects 方法是不须要传入参数的,它返回的是当前工程和当前工程下面的全部子工程的列表。上面演示的内容其实咱们不常常用到的,这里简单的介绍下就是为了说明 gradle 给咱们提供了好多方法来供咱们调用,在多工程的环境下咱们能够灵活的使用它们来达到咱们的要求,下面咱们就步入正题来看看在多工程状况下,gradle 是如何来编译,打包各自工程的。这里咱们添加些内容到 build.gradle 文件,内容见清单 21。

清单 21. 添加到 build.gradle 文件中的内容
 subprojects{ 
 apply plugin: 'java'
 }

 

而后咱们用命令 gradle build,发现主工程下面的全部子工程都新增了一个 build 文件夹,这个文件夹下包含编译生成的 class 文件和 jar 文件,而主工程的 src 下的代码却没有被编译,打包。那么咱们怎样作能让主工程和子工程同时被编译,打包呢?方法很简单,咱们只须要在 build.gradle 文件中增长 apply plugin: 'java' 这么一行代码,如今完整的 build.gradle 内容见清单 22。

清单 22. 完整的 build.gradle 文件内容
 apply plugin: 'java'
 subprojects{ 
 apply plugin: 'java'
 }

 

是否是很难想象,就这么几行代码就完成了将全部工程中的代码都编译了而且都打成了 jar 文件。有的朋友会问了,若是子工程与主工程他们打成的包不同,有的是须要 jar 包,有的须要打成 war 包等等,这样的需求咱们该怎样作呢,很简单咱们只须要在须要打成 war 包的工程下面新创建个 build.gradle 文件,该文件内容为 apply plugin: 'war',而后咱们咱们在主工程目录下使用 gradle build 命令便可生成咱们须要的 war 包了,Gradle 就是使用这种方法来知足那种差别性的需求的。

使用 Ant 的朋友们必定会深有感触的吧!也许有些朋友会有反面的一些声音,尤为对那些 Ant 的热爱者们,必定会说,Ant 若是你使用的好,封装的好同样能够很简洁而且也能达到这个效果的,的确是这样的,Gradle 只不过是把咱们常常要使用的一些功能项给封装成了方法,而后咱们调用这些方法便可了,再说了,Gradle 调用 Ant 脚本也是能够的,若是你必定要用 Ant, 那么你用 Gradle 来组织一下逻辑也是不错的选择。下面咱们简单看下在 Gradle 中式怎样来调用 Ant 脚本的。

Gradle 中调用 Ant 脚本

首先咱们创建 Ant 文件 build.xml, 文件详细内容见清单 23.

清单 23. build.xml 文件内容
 <project> 
    <target name="hello"> 
        <echo>Hello, from Ant</echo> 
    </target> 
 </project>

 

而后咱们在创建个 build.gradle 文件,文件详细内容见清单 24。

清单 24. build.gradle 文件内容
 ant.importBuild 'build.xml'

 

简单吧,一句话的事情而已,呵呵。而后咱们使用 gradle hello 命令来看下结果,结果见清单 25。

清单 25. Gradle 调用 Ant 文件的运行结果
 E:\gdcc\me\gradle-0.9-preview-1\samples\userguide\ant\hello>gradle hello 
 :hello 
 [ant:echo] Hello, from Ant 

 BUILD SUCCESSFUL 

 Total time: 9.734 secs

 

能够看出,的确调用的是 Ant 的 build.xml 文件吧。

总结

本 教程通具体实例来说解如何使用 Gradle 来构建工程的,并在具体实例中引入咱们熟悉的 Ant 来对比完成,这样能使 Ant 的爱好者们能更快的上手,并能一目了然的看到二者的优缺点,最后并讲解了怎样和 Ant 来集成,每个实例都是经过重新建工程开始一步一步的带领你们来继续的,咱们知道仅仅经过一片文章来很详细的将 Gradle 的方方面面都阐述的很清楚,那是不可能的,本教程提供了最基本,最基础的开发过程,任何复杂的事务归根结底仍是源于基础,我一贯倡导,“授之以鱼,不如授 之以渔”,我想只要方向对了,知道如何下手了,就不会有大的失误。最后祝你们工做顺利。

参考资料

学习

得到产品和技术

相关文章
相关标签/搜索