Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Next-Generation Builds with Gradle

Next-Generation Builds with Gradle

Java builds are mostly dominated by the tools Ant and Maven. Ant provides you with a flexible definition of build logic and a wide breath of existing tasks. Maven defines a standardized build lifecycle and layout. Make no compromises by using Gradle, the next generation of build tools. This presentation gives a practical introduction of Gradle's most important features and migration paths from existing builds.

Benjamin Muschko

July 01, 2012
Tweet

More Decks by Benjamin Muschko

Other Decks in Programming

Transcript

  1. Gradle! •  Java/Groovy developer with 10 years of experience • 

    Gaelyk and Gradle contributor •  Author of various plugins for Grails, Gradle, Gaelyk •  GroovyMag author •  Follow me on Twitter: @bmuschko •  Fork me on GitHub: bmuschko About Me 1
  2. Gradle! •  Flexible, extensible Open Source build tool •  Core

    written in Java, scripts in Groovy DSL •  Dependency management & multi-project support •  Convention over Configuration •  Hosted on GitHub, first release in April 2008 What is it? 2
  3. Gradle! Best of all Worlds Gradle! Flexibility Full Control Chaining

    of Targets Dependency Management Convention over Configuration Multi-module Projects Extensibility via Mojos Groovy DSL on top of Ant } 4
  4. Gradle! •  Ease of migration •  Add custom logic using

    tasks and plugins •  Gradle wrapper (run Gradle without installation) •  Incremental builds (only build what changed) •  Gradle daemon (avoid startup cost) •  Rich CLI (e.g. GUI, dry-run, camel case) Gradle Goodies 5
  5. Gradle! •  IDE support needs to get better •  Eclipse

    STS provides plugin with rudimentary DSL support •  IntelliJ 11 has minimal support •  NetBeans has plugin developed by community •  Eclipse, Idea plugins to the rescue •  Plugin ecosystem needs to catch up •  no central repository •  no plugin descriptor •  your favorite plugin might not exist •  Gradle doesn’t support project archetypes Gradle Pain Points 6
  6. Gradle! apply plugin: 'java' Convention over Configuration sourceSets {! main

    {! java {! srcDir 'src/main/java'! }! resources {! srcDir 'src/main/resources'! }! }! test {! java {! srcDir 'src/test/java'! }! resources {! srcDir 'src/test/resources'! }! }! }! 9
  7. Gradle! apply plugin: 'java' Customizing Default Layout sourceSets {! main

    {! java {! srcDir 'src'! } ! }! test {! java {! srcDir 'test'! } ! }! }! ! buildDir = 'target'! archivesBaseName = 'mcjug'! version = 1.1! 10
  8. Gradle! repositories {! mavenCentral()! mavenRepo name: 'InternalRepo' url: 'http://repo.internal.it'! add(new

    org.apache.ivy.plugins.resolver.URLResolver()) {! name = 'Cloud Repo'! addArtifactPattern """http://cloud.repo.com/downloads/libs/! [module]-[revision].[ext]"""! } ! flatDir dirs: '/home/gradle/libs' ! }! ! dependencies {! compile group: 'log4j', name: 'log4j', version: '1.2.15',! transitive: false! compile('company:api:1.0') {! exclude module: 'shared'! }! testCompile 'junit:junit:4.+'! runtime 'taglibs:standard:1.1.2', 'javax.servlet:jstl:1.1.2'! }! Dependency Management 11
  9. Gradle! apply plugin: 'java'! ! sourceCompatibility = 1.5! version =

    '1.0'! ! repositories {! mavenCentral()! }! ! dependencies {! compile 'commons-lang:commons-lang:2.3'! testCompile group: 'junit', name: 'junit', version: '4.+'! }! ! jar {! manifest {! attributes 'Implementation-Title': 'MCJUG example',! 'Implementation-Version': version! }! } Java Build Example 12
  10. Gradle! > gradle build! :compileJava Compiles Java sources ! :processResources

    Copies resources to classes dir! :classes Assembles the main classes! :jar Creates JAR artifact! :assemble Assembles all archives! :compileTestJava Compiles Java test sources! :processTestResources Copies test resources to classes dir! :testClasses Assembles the test classes! :test Runs the unit tests! :check Runs all checks! :build Assembles and tests project! ! BUILD SUCCESSFUL! ! Total time: 1 secs Building a Java project 13
  11. Gradle! Custom Logic •  Declare task in build script using

    Gradle DSL •  written in Groovy •  Ant tasks reusable out-of-the-box •  hooks into specific phase of execution lifecycle •  can apply additional task rule •  can be chained and imported if defined in separate script •  Custom task •  written as class that extends Gradle`s DefaultTask! •  describes behavior, gets applied to build script •  Custom plugin •  bundles more complex logic •  wide range of existing plugins 14
  12. Gradle! Task Example defaultTasks 'clean', 'run'! ! task clean <<

    {! ant.delete(dir: 'output')! println 'Deleted output directory'! }! ! task run(dependsOn: clean) << {! println 'Default Running!'! }! ! task setConfig {! description = 'Sets headless system property.'! setHeadless()! } ! ! def setHeadless() {! System.setProperty('java.awt.headless', 'true')! } 15
  13. Gradle! Build Lifecycle •  Gradle builds dependency graph (DAG) • 

    Your build script defines dependency graph •  Three distinct build phases •  Initialization •  Configuration •  Execution •  Multi-module projects require settings.gradle 19
  14. Gradle! Custom Task Example task depPersist(type: DependenciesTask) {! println 'Writes

    dependencies to file.'! output = file('dependencies.txt')! } ! ! import org.gradle.api.DefaultTask! ! class DependenciesTask extends DefaultTask {! File output! ! @TaskAction! void execute() {! def text = new StringBuilder()! "text <<= 'gradle dependencies'.execute().text! "output << text! }! }! 16
  15. Gradle! Plugin Example •  Plugin implementation! ! package org.mcjug !

    ! import org.gradle.api.Plugin! import org.gradle.api.Project! ! class ExamplePlugin implements Plugin<Project> {! @Override! void apply(Project project) {! // Your logic goes here! }! } ! •  Optional manifest META-INF/gradle-plugins/example.properties implementation-class=com.mcjug.ExamplePlugin 17
  16. Gradle! Existing Plugins •  Standard Plugins •  Language Plugins: Java,

    Groovy, Scala, Antlr •  Integration Plugins: WAR, Jetty, Maven, OSGI, Application •  Development Plugins: Eclipse, IDEA, Code Quality, Sonar •  Third Party Plugins •  Language Plugins: Clojuresque •  Integration Plugins: Android, GWT, AspectJ, Tomcat, GAE •  Development Plugins: Emma, FindBugs, CheckStyle, JSLint …and many more 18
  17. Gradle! Using Ant within Gradle •  build.xml ! <project>! <target

    name="run" description="Prints message">! <echo>Hello MCJUG!</echo>! </target>! </project>! ! ! •  build.gradle! ! ant.importBuild 'build.xml'! ! task echo << {! ant.echo 'Super simple migration'! }! 20
  18. Gradle! Migration from Ant •  Existing build.xml can be imported

    •  Ant targets get treated as Gradle tasks •  AntBuilder implicitly available in build.gradle •  All existing standard Ant tasks available •  dependsOn doesn`t respect execution order  Migration is very easy, can be done gradually 21
  19. <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/xsd/maven-4.0.0.xsd">! <modelVersion>4.0.0</modelVersion> ! <groupId>de.muschko</groupId>! <artifactId>maven_gradle_comparison</artifactId>! <packaging>jar</packaging>!

    <name>MCJUG example</name>! <version>1.0</version> ! <build>! <plugins> ! <plugin>! <groupId>org.apache.maven.plugins</groupId>! <artifactId>maven-compiler-plugin</artifactId>! <version>2.3.2</version>! <configuration>! <source>1.5</source> ! </configuration>! </plugin>! <plugin>! <groupId>org.apache.maven.plugins</groupId>! <artifactId>maven-jar-plugin</artifactId>! <version>2.3.1</version>! <configuration>! <archive>! <manifest>! <addDefaultImplementationEntries>true</addDefaultImplementationEntries>! </manifest>! </archive>! </configuration>! </plugin>! </plugins>! </build>! <dependencies>! <dependency>! <groupId>commons-lang</groupId>! <artifactId>commons-lang</artifactId>! <version>2.3</version>! <scope>compile</scope>! </dependency>! <dependency>! <groupId>junit</groupId>! <artifactId>junit</artifactId>! <version>4.4</version>! <scope>test</scope>! </dependency>! </dependencies>! </project>! apply plugin: 'java'! ! sourceCompatibility = 1.5! version = 1.0! ! repositories {! mavenCentral()! }! ! dependencies {! compile 'commons-lang:commons-lang:2.3'! testCompile 'junit:junit:4.4'! }! ! jar {! manifest {! attributes 'Implementation-Title': 'MCJUG example',! 'Implementation-Version': version! }! } 22 50% less Gradle! Maven vs. Gradle
  20. Gradle! Migration from Maven •  Existing pom.xml cannot be referenced/reused

    •  Support for multi-module projects •  Gradle provides Maven plugin •  maven2gradle eases the pain •  First-class citizen support on Gradle roadmap  Tools available, full migration required 23
  21. Gradle! Multi-module Example •  Parent build.gradle! ! allprojects {! apply

    plugin: 'java'! version = 1.0! }! ! subprojects { ! sourceCompatibility = 1.6! targetCompatibility = 1.6! ! repositories {! mavenCentral()! }! }! ! •  settings.gradle ! include 'common', 'api', 'web'! 25
  22. Gradle! Multi-module Example •  Web module build.gradle! ! project(':web') {!

    apply plugin: 'war'! apply plugin: 'jetty' ! ! dependencies { ! compile project(':common'),! project(':api')! ! runtime 'taglibs:standard:1.1.2',! 'javax.servlet:jstl:1.1.2'! ! providedCompile 'javax.servlet:servlet-api:2.5',! 'javax.servlet:jsp-api:2.0'! }! }! 26
  23. Gradle! Multi-module Projects •  If you did it in Maven

    you can easily do it in Gradle! •  Layout is totally flexible •  Number of build.gradle files is >= 1 •  settings.gradle defines included modules •  allprojects applies to project and subprojects •  subprojects just applies to subprojects 27
  24. Gradle! Links •  Gradle home •  http://www.gradle.org/! •  Gradle cookbook

    •  http://gradle.codehaus.org/Cookbook •  Gradle non-standard plugins •  http://docs.codehaus.org/display/GRADLE/Plugins! •  Presentation & source code •  http://github.com/bmuschko/presentations! 28