精华内容
下载资源
问答
  • Gradle和Maven

    2015-12-29 19:38:14
    Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同...
    Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同版本,然后部署。整个过程进行自动化操作是很有必要的。

    整个过程可以分成以下几个步骤:
    •编译源代码
    •运行单元测试和集成测试
    •执行静态代码分析、生成分析报告
    •创建发布版本
    •部署到目标环境
    •部署传递过程
    •执行冒烟测试和自动功能测试
    如果你手工去执行每一个步骤无疑效率比较低而且容易出错,有了自动化构建你只需要自定义你的构建逻辑,剩下的事情交给工具去完成。

    虽然两者都是项目工具,但是maven现在已经是行业标准,Gradle是后起之秀,很多人对他的了解都是从android studio中得到的,Gradle抛弃了Maven的基于XML的繁琐配置,众所周知XML的阅读体验比较差,对于机器来说虽然容易识别,但毕竟是由人去维护的。取而代之的是Gradle采用了领域特定语言Groovy的配置,大大简化了构建代码的行数,比如在Maven中你要引入一个依赖:

    <properties>
    <kaptcha.version>2.3</kaptcha.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>com.google.code.kaptcha</groupId>
    <artifactId>kaptcha</artifactId>
    <version>${kaptcha.version}</version>
    <classifier>jdk15</classifier>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    </dependency>
    </dependencies>


    然后我将其转换成Gradle脚本,结果是惊人的:

    dependencies {
    compile('org.springframework:spring-core:2.5.6')
    compile('org.springframework:spring-beans:2.5.6')
    compile('org.springframework:spring-context:2.5.6')
    compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
    testCompile('junit:junit:4.7')
    }

    注意配置从原来的28行缩减至7行!这还不算我省略的一些父POM配置。依赖的groupId、artifactId、 version,scope甚至是classfier,一点都不少。较之于Maven或者Ant的XML配置脚本,Gradle使用的Grovvy脚本杀伤力太大了,爱美之心,人皆有之,相比于七旬老妇松松垮垮的皱纹,大家肯定都喜欢少女紧致的脸蛋,XML就是那老妇的皱纹。

    Gradle给我最大的有点是两点。其一是简洁,基于Groovy的紧凑脚本实在让人爱不释手,在表述意图方面也没有什么不清晰的地方。其二是灵活,各种在Maven中难以下手的事情,在Gradle就是小菜一碟,比如修改现有的构建生命周期,几行配置就完成了,同样的事情,在Maven中你必须编写一个插件,那对于一个刚入门的用户来说,没个一两天几乎是不可能完成的任务。
    展开全文
  • Gradle和Maven对比

    2017-09-10 19:17:41
    Gradle和Maven的区别对比

    原文出处:http://www.cnblogs.com/huang0925/p/5209563.html

    Java世界中主要有三大构建工具:Ant、Maven和Gradle。经过几年的发展,Ant几乎销声匿迹、Maven也日薄西山,而Gradle的发展则如日中天。笔者有幸见证了Maven的没落和Gradle的兴起。Maven的主要功能主要分为5点,分别是依赖管理系统、多模块构建、一致的项目结构、一致的构建模型和插件机制。我们可以从这五个方面来分析一下Gradle比起Maven的先进之处。

    依赖管理系统

    Maven为Java世界引入了一个新的依赖管理系统。在Java世界中,可以用groupId、artifactId、version组成的Coordination(坐标)唯一标识一个依赖。任何基于Maven构建的项目自身也必须定义这三项属性,生成的包可以是Jar包,也可以是war包或者ear包。一个典型的依赖引用如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
    

    从上面可以看出当引用一个依赖时,version可以省略掉,这样在获取依赖时会选择最新的版本。而存储这些组件的仓库有远程仓库和本地仓库之分。远程仓库可以使用世界公用的central仓库,也可以使用Apache Nexus自建私有仓库;本地仓库则在本地计算机上。通过Maven安装目录下的settings.xml文件可以配置本地仓库的路径,以及采用的远程仓库的地址。

    Gradle在设计的时候基本沿用了Maven的这套依赖管理体系。不过它在引用依赖时还是进行了一些改进。首先引用依赖方面变得非常简洁。

    1
    2
    3
    4
    
    dependencies {
        compile 'org.hibernate:hibernate-core:3.6.7.Final'
        testCompile junit:junit:4.+'
    }
    

    第二,Maven和Gradle对依赖项的scope有所不同。在Maven世界中,一个依赖项有6种scope,分别是complie(默认)、provided、runtime、test、system、import。而grade将其简化为了4种,compile、runtime、testCompile、testRuntime。那么如果想在gradle使用类似于provided的scope怎么办?别着急,由于gradle语言的强大表现力,我们可以轻松编写代码来实现类似于provided scope的概念(例如How to use provided scope for jar file in Gradle build?)。

    第三点是Gradle支持动态的版本依赖。在版本号后面使用+号的方式可以实现动态的版本管理。

    第四点是在解决依赖冲突方面Gradle的实现机制更加明确。使用Maven和Gradle进行依赖管理时都采用的是传递性依赖;而如果多个依赖项指向同一个依赖项的不同版本时就会引起依赖冲突。而Maven处理这种依赖关系往往是噩梦一般的存在。而Gradle在解决依赖冲突方面相对来说比较明确。在Chapter 23. Dependency Management中的23.2.3章节详细解读了gradle是如何处理版本冲突的。

    多模块构建

    在SOA和微服务的浪潮下,将一个项目分解为多个模块已经是很通用的一种方式。在Maven中需要定义个parent POM作为一组module的聚合POM。在该POM中可以使用<modules>标签来定义一组子模块。parent POM不会有什么实际构建产出。而parent POM中的build配置以及依赖配置都会自动继承给子module。

    而Gradle也支持多模块构建。而在parent的build.gradle中可以使用allprojects和subprojects代码块来分别定义里面的配置是应用于所有项目还是子项目。对于子模块的定义是放置在setttings.gradle文件中的。在gradle的设计当中,每个模块都是Project的对象实例。而在parent build.gradle中通过allprojects或subprojects可以对这些对象进行各种操作。这无疑比Maven要灵活的多。

    比如在parent的build.gradle中有以下代码:

    1
    2
    3
    
    allprojects {
        task hello << { task -> println "I'm $task.project.name" }
    }
    

    执行命令gradle -q hello会依次打印出父module以及各个submodule的项目名称。这种强大的能力能让gradle对各个模块具有更强的定制化。

    一致的项目结构

    在Ant时代大家创建Java项目目录时比较随意,然后通过Ant配置指定哪些属于source,那些属于testSource等。而Maven在设计之初的理念就是Conversion over configuration(约定大于配置)。其制定了一套项目目录结构作为标准的Java项目结构。一个典型的Maven项目结构如下:

    Gradle也沿用了这一标准的目录结构。如果你在Gradle项目中使用了标准的Maven项目结构的话,那么在Gradle中也无需进行多余的配置,只需在文件中包含apply plugin:'java',系统会自动识别source、resource、test srouce、 test resource等相应资源。不过Gradle作为JVM上的构建工具,也同时支持groovy、scala等源代码的构建,甚至支持Java、groovy、scala语言的混合构建。虽然Maven通过一些插件(比如maven-scala-plugin)也能达到相同目的,但配置方面显然Gradle要更优雅一些。

    一致的构建模型

    为了解决Ant中对项目构建活动缺乏标准化的问题,Maven特意设置了标准的项目构建周期,其默认的构建周期如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    <phases>
      <phase>validate</phase>
      <phase>initialize</phase>
      <phase>generate-sources</phase>
      <phase>process-sources</phase>
      <phase>generate-resources</phase>
      <phase>process-resources</phase>
      <phase>compile</phase>
      <phase>process-classes</phase>
      <phase>generate-test-sources</phase>
      <phase>process-test-sources</phase>
      <phase>generate-test-resources</phase>
      <phase>process-test-resources</phase>
      <phase>test-compile</phase>
      <phase>process-test-classes</phase>
      <phase>test</phase>
      <phase>prepare-package</phase>
      <phase>package</phase>
      <phase>pre-integration-test</phase>
      <phase>integration-test</phase>
      <phase>post-integration-test</phase>
      <phase>verify</phase>
      <phase>install</phase>
      <phase>deploy</phase>
    </phases>
    

    而这种构建周期也是Maven最为人诟病的地方。因为Maven将项目的构建周期限制的太死,你无法在构建周期中添加新的phase,只能将插件绑定到已有的phase上。而现在项目的构建过程变得越来越复杂,而且多样化,显然Maven对这种复杂度缺少足够的应变能力。比如你想在项目构建过程中进行一项压缩所有javascript的任务,那么就要绑定到Maven的现有的某个phase上,而显然貌似放在哪个phase都不太合适。而且这些phase都是串行的,整个执行下来是一条线,这也限制了Maven的构建效率。而Gradle在构建模型上则非常灵活。在Gradle世界里可以轻松创建一个task,并随时通过depends语法建立与已有task的依赖关系。甚至对于Java项目的构建来说,Gradle是通过名为java的插件来包含了一个对Java项目的构建周期,这等于Gradle本身直接与项目构建周期是解耦的。

    插件机制

    Maven和Gradle设计时都采用了插件机制。但显然Gradle更胜一筹。主要原因在于Maven是基于XML进行配置。所以其配置语法太受限于XML。即使实现很小的功能都需要设计一个插件,建立其与XML配置的关联。比如想在Maven中执行一条shell命令,其配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2</version>
      <executions>
        <execution>
          <id>drop DB => db_name</id>
          <phase>pre-integration-test</phase>
          <goals>
            <goal>exec</goal>
          </goals>
          <configuration>
            <executable>curl</executable>
            <arguments>
              <argument>-s</argument>
              <argument>-S</argument>
              <argument>-X</argument>
              <argument>DELETE</argument>
              <argument>http://${db.server}:${db.port}/db_name</argument>
            </arguments>
          </configuration>
        </execution>
      </executions>
    </plugin>
    

    而在Gradle中则一切变得非常简单。

    1
    2
    3
    
    task dropDB(type: Exec) {
     commandLine curl,-s,s,-x,DELETE,"http://${db.server}:{db.port}/db_name"
    }
    

    在创建自定义插件方面,Maven和Gradle的机制都差不多,都是继承自插件基类,然后实现要求的方法。这里就不展开说明。


    从以上五个方面可以看出Maven和Gradle的主要差异。Maven的设计核心Convention Over Configuration被Gradle更加发扬光大,而Gradle的配置即代码又超越了Maven。在Gradle中任何配置都可以作为代码被执行的,我们也可以随时使用已有的Ant脚本(Ant task是Gradle中的一等公民)、Java类库、Groovy类库来辅助完成构建任务的编写。

    这种采用本身语言实现的DSL对本身语言项目进行构建管理的例子比比皆是。比如Rake和Ruby、Grunt和JavaScript、Sbt和Ruby…..而Gradle之所以使用Groovy语言实现,是因为Groovy比Java语言更具表现力,其语法特性更丰富,又兼具函数式的特点。这几年兴起的语言(比如Scala、Go、Swift)都属于强类型的语言,兼具面向对象和函数式的特点。

    最后想说的Gradle的命令行比Maven的要强大的多。以前写过一篇文章专门讲述了Gradle的命令行操作,详情请见Gradle命令行黑魔法

    展开全文
  • 目录深入了解gradle和maven的区别gradle和maven的比较可扩展性性能比较依赖的区别从maven迁移到gradle自动转换转换依赖转换repositories仓库控制依赖的版本多模块项目profile和属性资源处理 深入了解gradle和maven的...

    深入了解gradle和maven的区别

    gradle和maven都可以用来构建java程序,甚至在某些情况下,两者还可以互相转换,那么他们两个的共同点和不同点是什么?我们如何在项目中选择使用哪种技术呢?一起来看看吧。

    gradle和maven的比较

    虽然gradle和maven都可以作为java程序的构建工具。但是两者还是有很大的不同之处的。我们可以从下面几个方面来进行分析。

    可扩展性

    Google选择gradle作为android的构建工具不是没有理由的,其中一个非常重要的原因就是因为gradle够灵活。一方面是因为gradle使用的是groovy或者kotlin语言作为脚本的编写语言,这样极大的提高了脚本的灵活性,但是其本质上的原因是gradle的基础架构能够支持这种灵活性。

    你可以使用gradle来构建native的C/C++程序,甚至扩展到任何语言的构建。

    相对而言,maven的灵活性就差一些,并且自定义起来也比较麻烦,但是maven的项目比较容易看懂,并且上手简单。

    所以如果你的项目没有太多自定义构建需求的话还是推荐使用maven,但是如果有自定义的构建需求,那么还是投入gradle的怀抱吧。

    性能比较

    虽然现在大家的机子性能都比较强劲,好像在做项目构建的时候性能的优势并不是那么的迫切,但是对于大型项目来说,一次构建可能会需要很长的时间,尤其对于自动化构建和CI的环境来说,当然希望这个构建是越快越好。

    Gradle和Maven都支持并行的项目构建和依赖解析。但是gradle的三个特点让gradle可以跑的比maven快上一点:

    • 增量构建

    gradle为了提升构建的效率,提出了增量构建的概念,为了实现增量构建,gradle将每一个task都分成了三部分,分别是input输入,任务本身和output输出。下图是一个典型的java编译的task。

    基础必看——深入了解gradle和maven的区别

    以上图为例,input就是目标jdk的版本,源代码等,output就是编译出来的class文件。

    增量构建的原理就是监控input的变化,只有input发送变化了,才重新执行task任务,否则gradle认为可以重用之前的执行结果。

    所以在编写gradle的task的时候,需要指定task的输入和输出。

    并且要注意只有会对输出结果产生变化的才能被称为输入,如果你定义了对初始结果完全无关的变量作为输入,则这些变量的变化会导致gradle重新执行task,导致了不必要的性能的损耗。

    还要注意不确定执行结果的任务,比如说同样的输入可能会得到不同的输出结果,那么这样的任务将不能够被配置为增量构建任务。

    • 构建缓存

    gradle可以重用同样input的输出作为缓存,大家可能会有疑问了,这个缓存和增量编译不是一个意思吗?

    在同一个机子上是的,但是缓存可以跨机器共享.如果你是在一个CI服务的话,build cache将会非常有用。因为developer的build可以直接从CI服务器上面拉取构建结果,非常的方便。

    • Gradle守护进程

    gradle会开启一个守护进程来和各个build任务进行交互,优点就是不需要每次构建都初始化需要的组件和服务。

    同时因为守护进程是一个一直运行的进程,除了可以避免每次JVM启动的开销之外,还可以缓存项目结构,文件,task和其他的信息,从而提升运行速度。

    我们可以运行 gradle –status 来查看正在运行的daemons进程。

    从Gradle 3.0之后,daemons是默认开启的,你可以使用 org.gradle.daemon=false 来禁止daemons。

    我们可以通过下面的几个图来直观的感受一下gradle和maven的性能比较:

    • 使用gradle和maven构建 Apache Commons Lang 3的比较:

    基础必看——深入了解gradle和maven的区别

    • 使用gradle和maven构建小项目(10个模块,每个模块50个源文件和50个测试文件)的比较:

    基础必看——深入了解gradle和maven的区别

    • 使用gradle和maven构建大项目(500个模块,每个模块100个源文件和100个测试文件)的比较:

    基础必看——深入了解gradle和maven的区别

    可以看到gradle性能的提升是非常明显的。

    依赖的区别

    gralde和maven都可以本地缓存依赖文件,并且都支持依赖文件的并行下载。

    在maven中只可以通过版本号来覆盖一个依赖项。而gradle更加灵活,你可以自定义依赖关系和替换规则,通过这些替换规则,gradle可以构建非常复杂的项目。

    从maven迁移到gradle

    因为maven出现的时间比较早,所以基本上所有的java项目都支持maven,但是并不是所有的项目都支持gradle。如果你有需要把maven项目迁移到gradle的想法,那么就一起来看看吧。

    根据我们之前的介绍,大家可以发现gradle和maven从本质上来说就是不同的,gradle通过task的DAG图来组织任务,而maven则是通过attach到phases的goals来执行任务。

    虽然两者的构建有很大的不同,但是得益于gradle和maven相识的各种约定规则,从maven移植到gradle并不是那么难。

    要想从maven移植到gradle,首先要了解下maven的build生命周期,maven的生命周期包含了clean,compile,test,package,verify,install和deploy这几个phase。

    我们需要将maven的生命周期phase转换为gradle的生命周期task。这里需要使用到gradle的Base Plugin,Java Plugin和Maven Publish Plugin。

    先看下怎么引入这三个plugin:

    plugins {
        id 'base'
        id 'java'
        id 'maven-publish'
    }
    

    clean会被转换成为clean task,compile会被转换成为classes task,test会被转换成为test task,package会被转换成为assemble task,verify 会被转换成为check task,install会被转换成为 Maven Publish Plugin 中的publishToMavenLocal task,deploy 会被转换成为Maven Publish Plugin 中的publish task。

    有了这些task之间的对应关系,我们就可以尝试进行maven到gradle的转换了。

    自动转换

    我们除了可以使用 gradle init 命令来创建一个gradle的架子之外,还可以使用这个命令来将maven项目转换成为gradle项目,gradle init命令会去读取pom文件,并将其转换成为gradle项目。

    转换依赖

    gradle和maven的依赖都包含了group ID, artifact ID 和版本号。两者本质上是一样的,只是形式不同,我们看一个转换的例子:

    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>
    

    上是一个maven的例子,我们看下gradle的例子怎写:

    dependencies {
        implementation 'log4j:log4j:1.2.12'  
    }
    

    可以看到gradle比maven写起来要简单很多。

    注意这里的implementation实际上是由 Java Plugin 来实现的。

    我们在maven的依赖中有时候还会用到scope选项,用来表示依赖的范围,我们看下这些范围该如何进行转换:

    • compile:

    在gradle可以有两种配置来替换compile,我们可以使用implementation或者api。

    前者在任何使用Java Plugin的gradle中都可以使用,而api只能在使用Java Library Plugin的项目中使用。

    当然两者是有区别的,如果你是构建应用程序或者webapp,那么推荐使用implementation,如果你是在构建Java libraries,那么推荐使用api。

    • runtime:

    可以替换成 runtimeOnly 。

    • test:

    gradle中的test分为两种,一种是编译test项目的时候需要,那么可以使用testImplementation,一种是运行test项目的时候需要,那么可以使用testRuntimeOnly。

    • provided:

    可以替换成为compileOnly。

    • import:

    在maven中,import经常用在dependencyManagement中,通常用来从一个pom文件中导入依赖项,从而保证项目中依赖项目版本的一致性。

    在gradle中,可以使用 platform() 或者 enforcedPlatform() 来导入pom文件:

    dependencies {
        implementation platform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE') 
    
        implementation 'com.google.code.gson:gson' 
        implementation 'dom4j:dom4j'
    }
    

    比如上面的例子中,我们导入了spring-boot-dependencies。因为这个pom中已经定义了依赖项的版本号,所以我们在后面引入gson的时候就不需要指定版本号了。

    platform和enforcedPlatform的区别在于,enforcedPlatform会将导入的pom版本号覆盖其他导入的版本号:

    dependencies {
        // import a BOM. The versions used in this file will override any other version found in the graph
        implementation enforcedPlatform('org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE')
    
        // define dependencies without versions
        implementation 'com.google.code.gson:gson'
        implementation 'dom4j:dom4j'
    
        // this version will be overridden by the one found in the BOM
        implementation 'org.codehaus.groovy:groovy:1.8.6'
    }
    

    转换repositories仓库

    gradle可以兼容使用maven或者lvy的repository。gradle没有默认的仓库地址,所以你必须手动指定一个。

    你可以在gradle使用maven的仓库:

    repositories {
        mavenCentral()
    }
    

    我们还可以直接指定maven仓库的地址:

    repositories {
        maven {
            url "http://repo.mycompany.com/maven2"
        }
    }
    

    如果你想使用maven本地的仓库,则可以这样使用:

    repositories {
        mavenLocal()
    }
    

    但是mavenLocal是不推荐使用的,为什么呢?

    mavenLocal只是maven在本地的一个cache,它包含的内容并不完整。比如说一个本地的maven repository module可能只包含了jar包文件,并没有包含source或者javadoc文件。那么我们将不能够在gradle中查看这个module的源代码,因为gradle会首先在maven本地的路径中查找这个module。

    并且本地的repository是不可信任的,因为里面的内容可以轻易被修改,并没有任何的验证机制。

    控制依赖的版本

    如果同一个项目中对同一个模块有不同版本的两个依赖的话,默认情况下Gradle会在解析完DAG之后,选择版本最高的那个依赖包。

    但是这样做并不一定就是正确的, 所以我们需要自定义依赖版本的功能。

    首先就是上面我们提到的使用platform()和enforcedPlatform() 来导入BOM(packaging类型是POM的)文件。

    如果我们项目中依赖了某个module,而这个module又依赖了另外的module,我们叫做传递依赖。在这种情况下,如果我们希望控制传递依赖的版本,比如说将传递依赖的版本升级为一个新的版本,那么可以使用dependency constraints:

    dependencies {
        implementation 'org.apache.httpcomponents:httpclient'
        constraints {
            implementation('org.apache.httpcomponents:httpclient:4.5.3') {
                because 'previous versions have a bug impacting this application'
            }
            implementation('commons-codec:commons-codec:1.11') {
                because 'version 1.9 pulled from httpclient has bugs affecting this application'
            }
        }
    }
    

    注意,dependency constraints只对传递依赖有效,如果上面的例子中commons-codec并不是传递依赖,那么将不会有任何影响。

    同时 Dependency constraints需要Gradle Module Metadata的支持,也就是说只有你的module是发布在gradle中才支持这个特性,如果是发布在maven或者ivy中是不支持的。

    上面讲的是传递依赖的版本升级。同样是传递依赖,如果本项目也需要使用到这个传递依赖的module,但是需要使用到更低的版本(因为默认gradle会使用最新的版本),就需要用到版本降级了。

    dependencies {
        implementation 'org.apache.httpcomponents:httpclient:4.5.4'
        implementation('commons-codec:commons-codec') {
            version {
                strictly '1.9'
            }
        }
    }
    

    我们可以在implementation中指定特定的version即可。

    strictly表示的是强制匹配特定的版本号,除了strictly之外,还有require,表示需要的版本号大于等于给定的版本号。prefer,如果没有指定其他的版本号,那么就使用prefer这个。reject,拒绝使用这个版本。

    除此之外,你还可以使用Java Platform Plugin来指定特定的platform,从而限制版本号。

    最后看一下如何exclude一个依赖:

    dependencies {
        implementation('commons-beanutils:commons-beanutils:1.9.4') {
            exclude group: 'commons-collections', module: 'commons-collections'
        }
    }
    

    多模块项目

    maven中可以创建多模块项目:

    <modules>
        <module>simple-weather</module>
        <module>simple-webapp</module>
    </modules>
    

    我们可以在gradle中做同样的事情settings.gradle:

    rootProject.name = 'simple-multi-module'  
    
    include 'simple-weather', 'simple-webapp'
    

    profile和属性

    maven中可以使用profile来区别不同的环境,在gradle中,我们可以定义好不同的profile文件,然后通过脚本来加载他们:

    build.gradle:

    if (!hasProperty('buildProfile')) ext.buildProfile = 'default'  
    
    apply from: "profile-${buildProfile}.gradle"  
    
    task greeting {
        doLast {
            println message  
        }
    }
    

    profile-default.gradle:

    ext.message = 'foobar'
    

    profile-test.gradle:

    ext.message = 'testing 1 2 3'
    

    我们可以这样来运行:

    
    > gradle greeting
    foobar
    
    > gradle -PbuildProfile=test greeting
    testing 1 2 3
    

    资源处理

    在maven中有一个process-resources阶段,可以执行resources:resources用来进行resource文件的拷贝操作。

    在Gradle中的Java plugin的processResources task也可以做相同的事情。

    比如我可以执行copy任务:

    task copyReport(type: Copy) {
        from file("buildDir/reports/my-report.pdf")
        into file("buildDir/toArchive")
    }
    

    更加复杂的拷贝:

    task copyPdfReportsForArchiving(type: Copy) {
        from "buildDir/reports"
        include "*.pdf"
        into "buildDir/toArchive"
    }
    

    当然拷贝还有更加复杂的应用。这里就不详细讲解了。

    展开全文
  • gradle和maven对比

    2020-09-17 18:56:19
    Gradle和maven有很多相似点,gradle充分考虑到maven库的价值,在jar包管理上完全支持maven Repository,很多属性乍眼一看就能反应过来maven中对应的是什么标签,大大降低maven到gradle的迁移难度,并在构建方面改善...

    Gradle作为一款基于Groovy语言的构建工具,已经吸引众多的ant,maven使用者转投gradle的怀抱,和Gradle相比,ant显得冗余复杂,maven显得有些死板落后,而gradle基于DSL语法,特点明显:简洁、灵活、可读性强。Gradle和maven有很多相似点,gradle充分考虑到maven库的价值,在jar包管理上完全支持maven Repository,很多属性乍眼一看就能反应过来maven中对应的是什么标签,大大降低maven到gradle的迁移难度,并在构建方面改善了很多maven的不足,,同时,gradle对比maven更好的面向ant用户,使用maven时,虽然能通过plugin来跑ant的命令,但是maven在任务实现主要靠的是插件以及自身的固定框架,Gradle在定义任务方面思想与ant非常相似,做了很好的集成。下面会主要介绍gradle在配置方面与maven的异同处,以及Gradle比较实用的命令。

    1.基础配置信息

    maven使用.pom文件,基于XML,gradle使用.gradle文件,基于Groovy,gradle去掉maven中需要固定配置的groupId,artfactId,package等基本参数,通过 apply plugin: ‘java’,apply plugin: 'war’来表示打包方式,也提供sourceCompatibility,version等一些实用的标签。

    2.依赖管理

    Gradle的jar包管理支持maven下Repository方式,也支持Ant的Ivy方式,由于maven的Repository已经非常成熟,gradle在兼容Repository做得非常方便,定义maven的repository:

    • mavenLocal() :maven 本地库
    • mavenCentral():maven 远程库
    • mavenRepo urls: 自定义库路径

    maven通过groupId、name和version到配置的Repository里寻找指定依赖中的Jar包。Gradle的生命周期更为复杂,但也支持Maven依赖中的构建生命周期,compile、runtime、testCompile和testRuntime分别对应项目不同阶段的依赖。 并且还简化maven的配置命令。
    Maven:

      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version> 
        <scope>test</scope>
      </dependency>
    

    Gradle:

      dependencies {    testCompile group:'junit', name: 'junit', version '4.11'}
    

    或者

      dependencies {    testCompile 'junit:junit:4.11'    }
    

    如果需要引用自己lib目录下jar包,maven需要在每个依赖加上 和标签或者在plugin里单独增加编译路径。而Gradle只需要加上

    compile fileTree(dir: 'libs', include: '*.jar')
    

    在多个路径下时:
    j

    arTree = fileTree(dir: 'libs', include: '*.jar')
    rootTree = new File(rootProject.rootDir, 'libs').getAbsolutePath()
    jarTree += fileTree(dir: rootTree, include: '*.jar')
    compile jarTree
    

    在依赖相关的命令行方面,gradle与maven比较相似,maven常用的分析依赖命令包括:

    • mvn dependency:analyz查看依赖;
    • mvn dependency:tree 查看项目直接和传递依赖;
    • mvn help:effective-pom查看有效的pom;
      在gradle中使用gradle dependencies 可以查看项目中包的依赖关系。加上-configuration来查看指定阶段的依赖情况,还可以-dependency来查看指定jar的依赖情况。

    3.多项目管理

    实际使用中,往往需要管理的都不是单单一个项目,maven使用依赖,继承,组成的概念,在父模块指定自己的子模块,并且准备一些各个子模块公用的资源,如插件,配置信息等等。将打包的模块与实现具体功能的模块分开的做法来管理多个项目。Gradle在这一方面做得更加清楚,划分更明确,学习gradle的多项目管理也很容易,在eclipse中安装完gradle插件之后,新建一个Gradle工程,选择flat-java-multiproject,生成的工程就是多项目管理一个示例。Gradle通过settings.gradle文件来指定工程的子项目,在构建的初始化阶段(Initialization),Gradle会根据settings.gradle 文件来判断有哪些子项目被include到了构建中,并为每一个子项目初始化一个Project对象,在构建脚本中通过project(‘:sub-project-name’)来引用子项目对应的Project对象。关于多项目配置有非常多,因此就简述一下常用的配置共享以及配置独享。

    • Allprojects属性,返回该Project对象以及其所有子项目。
    • subprojects属性,返回该Project所有子项目。
    • project(‘:sub-project-name’)来设置对应的子项目的配置。
    • configure(subprojects.findAll {it.name.contains(‘XXX’)})来找符合要求的子项目。

    在子项目的build.gradle文件里添加自己独有的配置。

    4.任务机制

    Maven相对于ant相比仅仅通过plugin提供任务机制,相比而言自由度小而且很难扩展,每定义一个功能都需要写一个插件,Ant中使用tagret标签的echo来指定命令,gradle使用groovy语言,自带task概念,与ant使用的build文件更加接近。一个Task表示一个逻辑上的执行单元。
    Gradle编写task的方式有很多,网上也能很容易搜索到相关的例子,在此简述有关task的一些实用命令以及自己一个常用的task:

    Task listJars(description: 'Display compile jars.') << {
           configurations.compile.each { File file -> println file.name }
    }
    

    这个task可以显示出当前项目下所有用于 compile 的 jar。
    常用命令:

    1. Task可以通过全名调用、前缀调用或首字母调用。
    2. gradle XXX -s/ gradle XXX -S
      当执行task有错误时,可以使用-s来查询详细的错误堆栈,-S输出全部堆栈信息。
    3. -continue
      比如执行gradle clean install -continue,即使遇到某些task失败也不会停止后续task的执行,一次性得到所有的构建错误。
    4. Gradle tasks / Gradle tasks all
      显示出当前目录下所有的task以及显示出task之间的依赖关系。

    最后,Gradle不足的地方就在于使用了groovy语言,熟悉一个新语言是需要学习成本的,而ant和maven都是使用xml来实现,不过groovy被称为是没有类型的java,对于java学习者来说还是容易接受的,这样提高了gradle在实际应用中的可行性。作为一个构建工具,Gradle能算得上非常好的选择。对于Gradle的一些简单介绍,希望能对大家有所帮助。

    5. 与docker的集成

    Docker 在构建镜像时有分段缓存机制,鼓励用户编写 Dockerfile 时充分利用分段构建(先下载依赖,再编译项目)。这一点 Maven 很好做到,因此官方在介绍最佳实践的文章中也是以 Maven 入手,从项目的编译到运行都在 Docker 容器中完成。
    Gradle 则有自身的一套缓存机制,放在 Docker 中则适得其反,无法被 Docker 有效缓存,导致构建效率低下(无法像 Maven 一样一个 POM 完成全部依赖的静态解析,且缓存机制是动态的,想静态又得用离线模式)。因此 Gradle 推荐的做法是在 build.gradle 中通过插件构建 Docker 镜像,而不是在容器中编译。实际上官方更推荐使用专门的 Gradle Build Server / Build Cache Server。

    Gradle项目打包并Docker部署

    6. 在shell中传入参数

    向Gradle:

    shell中

    ./gradlew collectSDK -Pflavor=gionee
    

    gradle脚本

    def flavor = project.hasProperty('flavor') ? flavor : "common"
    

    maven相对麻烦,不细说

    刘持老师的博文《maven到Gradle,一些对比和分享》

    展开全文
  • 本文主要进行Gradle和Maven构建工具的介绍,以及介绍如何使用Gradle和Maven构建一个简单的Java工程。
  • GradleAndMaven:通过Gradle和Maven构建的多模块项目
  • 深入了解gradle和maven的区别

    千次阅读 2021-02-10 12:10:01
    gradle和maven都可以用来构建java程序,甚至在某些情况下,两者还可以互相转换,那么他们两个的共同点和不同点是什么?我们如何在项目中选择使用哪种技术呢?一起来看看吧。
  • gradle和maven区别

    万次阅读 2018-01-25 17:36:53
    ----------------------...Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为
  • 关于Maven的配置:用过Maven的开发人员应该知道Maven可以通过配置 conf文件夹下面的settings.xml文件来修改maven下载的包,默认是下在c盘的用户文件夹下的.m2中,日积月累.m2会越来越庞大,自然会影响windows的响应,...
  • 用过Maven的开发人员应该知道Maven可以通过配置 conf文件夹下面的settings.xml文件来修改maven下载的包,默认是下在c盘的用户文件夹下的.m2中,日积月累.m2会越来越庞大,自然会影响windows的响应,所以一般我们都会...
  • Gradle和Maven区别

    千次阅读 2019-05-11 00:27:21
    Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同...
  • spock-example:Spock示例规范以及现成的Gradle和Maven构建
  • Gradle和Maven的区别

    2021-03-12 11:13:20
    Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同...
  • gradle和maven Java哲学的一个中心方面是名称很重要 。 Brian Goetz,Java语言架构师和Java Concurrency in Practice的作者 配套 如果您为“ acme.com”工作,并且正在开发一个名为“ foo”的项目,则约定是您...
  • kotlin-jlink-examples 示例如何在gradle和maven中将jlink与kotlin一起使用。 您可以从以下子目录打开项目: — Gradle示例 — Maven示例
  • Gradle和Maven使用阿里云国内镜像

    千次阅读 2019-07-30 02:02:58
    Gradle和Maven使用阿里云国内镜像Gradle 使用阿里云国内镜像Maven Gradle 使用阿里云国内镜像 1、对单个项目生效,在项目中的build.gradle修改内容 buildscript { repositories { maven { url '...
  • Java世界中主要有三大构建工具:Ant、Maven和GradleMaven的主要功能是:依赖管理系统、多模块构建、一致的项目结构、一致的构建模型插件机制。maven使用groupId、artifactId、version组成的Coordination(坐标)...
  • gradle和maven有什么区别?

    千次阅读 2016-03-25 15:55:49
    Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同...
  • Java世界中主要有三大构建工具:Ant、Maven和GradleMaven的主要功能是:依赖管理系统、多模块构建、一致的项目结构、一致的构建模型插件机制。maven使用groupId、artifactId、version组成的Coordination(坐标)...
  • gradle和maven的对比

    2020-04-08 16:42:11
    Java世界中主要有三大构建工具:Ant、Maven和Gradle。经过几年的发展,Ant几乎销声匿迹、Maven也日薄西山,而Gradle的发展则如日中天。笔者有幸见证了Maven的没落和Gradle的兴起。Maven的主要功能主要分为5点,分别...
  • 因为我本地开发,既需要gradle也需要maven,所以对这两个本地仓库做了不同的目录区分,由此有了以下的总结: Gradle: mavenLocal(),下载顺序是:USER_HOME/.m2/settings.xml >> M2_HOME/conf/settings.xml >...
  • Gradle和Maven性能对比

    千次阅读 2019-11-24 04:33:08
    Gradle目前已经出到6.0版本了,想当初我第一次了解到Gradle的时候,它仅有2.0版本,这些年来一直不断迭代优化,现在可以说是非常成熟好用的一款工具。如果大家还在使用Maven,我建议大家学习一下Gradle,现在...
  • 如果您使用的是Java构建工具,那么可以使用简单的HTTP请求,Ant + Ivy,Gradle和Maven下载和使用TeamCity构建配置生成的二进制文件。 怎么样? 继续阅读。 构建配置“ id” 在检索任何构建配置的工件之前,您需要...
  • Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同...
  • 经过这么多年的发展,终于Ant几乎快销声匿迹了,Maven和Gradle在项目开发中用得比较多,其中以Gradle发展得最好。Maven的主要功能是多模块构建、依赖管理系统、一致的项目结构、一致的项目构建模型插件机制。在此...
  • 持久层快速入门系列一bboss持久层gradle和maven坐标及应用介绍首先在应用中导入bboss 持久层(bboss persistent版本号5.0.2.9,以实际为准:查看最新版本号):maven坐标com.bbossgroupsbboss-persistent5.0.2.9gradle...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,365
精华内容 1,746
关键字:

gradle和maven