gradle talk, javarsovia 2010

70
2010 Gradle Tomek Kaczanowski http://kaczanowscy.pl/tomek Gradle

Upload: tomek-kaczanowski

Post on 26-Jan-2015

104 views

Category:

Technology


0 download

DESCRIPTION

Slides from my Gradle talk, Javarsovia 2010.

TRANSCRIPT

Page 1: Gradle talk, Javarsovia 2010

2010

Gradle

Tomek Kaczanowskihttp://kaczanowscy.pl/tomek

Gradle

Page 2: Gradle talk, Javarsovia 2010

2010

IMPORTANT

All code samples are compatible with version

0.9-preview-3

Page 3: Gradle talk, Javarsovia 2010

2010

There are no simple builds

Page 4: Gradle talk, Javarsovia 2010

2010

Page 5: Gradle talk, Javarsovia 2010

2010

• Flexible build tool

• Based on convention over configuration idea

• Groovy (DSL)

• Open source

• Project Manager: Hans Docter

• GitHub

• First release: April 2008

making the impossible possible, the possible easy, and the easy elegant

-- Moshé Feldenkrais

Page 6: Gradle talk, Javarsovia 2010

2010

Table of Contents• Warm-up

– Command line, GUI, tasks, DAG

• Competition– Ant, Maven & Co

• MyProject: Core, UI:Web, UI:Swing– CoC + customization

– Compilation (Java, Groovy), JAR/WAR,

– artifacts handling (repositories & dependencies),

– custom logic (tasks)

– Gradle & Ant

– Multi-module builds• Layout

• Partial builds

Page 7: Gradle talk, Javarsovia 2010

2010

Intro

Page 8: Gradle talk, Javarsovia 2010

2010

Intro - DAG

• Read and manipulate graph of tasks, e.g.:

task release(dependsOn: assemble) << { println 'We release now‘

}

gradle.taskGraph.whenReady { taskGraph ->

if (taskGraph.hasTask(':release')) { version = '1.0‘

} else {version = '1.0-SNAPSHOT‘

} }

Page 9: Gradle talk, Javarsovia 2010

2010

Intro - DAG

• Read and manipulate graph of tasks, e.g.:

gradle.taskGraph.beforeTask { Task task -> println "executing $task ..."}

gradle.taskGraph.afterTask { Task task, TaskState state ->

if (state.failure) {println "FAILED"

}else {

println "done"}

}

Page 10: Gradle talk, Javarsovia 2010

2010

Intro - summary

• DSL• Command line, GUI (+ IDE plugins)

– Reports– Prunning of tasks tree (-x)– User friendly (camel case, dry run)

• Rich tasks layer– Tasks dependencies– DAG– Runtime manipulation

Page 11: Gradle talk, Javarsovia 2010

2010

Frameworkitis is the disease that a framework

wants to do too much for you or it does it in a way that you don't want but you can't change it. It's fun to get all this functionality for free, but it hurts when the free functionality gets in the way. […] To get the desired behavior you start to fight against the framework. And at this point you often start to lose, because it's difficult to bend the framework in a direction it didn't anticipate.

[…] Frameworks try to be in control and tell you when to do what. A toolkit gives you the building blocks but leaves it up to you to be in control.

Erich Gamma, www.artima.com

Page 12: Gradle talk, Javarsovia 2010

2010

Page 13: Gradle talk, Javarsovia 2010

2010

Page 14: Gradle talk, Javarsovia 2010

2010

Page 15: Gradle talk, Javarsovia 2010

2010

MyProject• Core

– Classes used by UI subprojects– Java

• UI:Web– Web application

• UI:Swing– Desktop application– Groovy

Page 16: Gradle talk, Javarsovia 2010

2010

Conventionover

configuration

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

Page 17: Gradle talk, Javarsovia 2010

2010

Conventionover

configuration

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

Page 18: Gradle talk, Javarsovia 2010

2010

Configurationis always possible

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

version="1.0-SNAPSHOT"

archivesBaseName = "whatever"

libsDirName="build/artifacts"

apply plugin: 'java'

Page 19: Gradle talk, Javarsovia 2010

2010

Configurationis always possible

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

.|-- build.gradle|-- src`-- test

Page 20: Gradle talk, Javarsovia 2010

2010

Configurationis always possible

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

.|-- build.gradle|-- src`-- test

apply plugin: 'java'

sourceSets { main { java { srcDir 'src' } } test { java { srcDir 'test' } }}

Page 21: Gradle talk, Javarsovia 2010

2010

Conventionover

configuration

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

Page 22: Gradle talk, Javarsovia 2010

2010

Conventionover

configuration

.|-- build.gradle`-- src |-- main | `-- java `-- test `-- java

apply plugin: 'java'

repositories { mavenCentral()}

dependencies { compile 'org.hibernate:hibernate:3.1.3', 'commons-lang:commons-lang:2.5' testCompile 'junit:junit:4.8.1'}

Page 23: Gradle talk, Javarsovia 2010

2010

apply plugin: 'java'

repositories { mavenCentral()}

configurations { pmd}

dependencies { compile 'org.hibernate:hibernate:3.1.3', 'commons-lang:commons-lang:2.5' testCompile 'junit:junit:4.8.1' pmd 'pmd:pmd:4.2.5'}

Groups of dependencies

Page 24: Gradle talk, Javarsovia 2010

2010

apply plugin: 'java'

version = '1.0-SNAPSHOT'

repositories {

mavenCentral()

}

dependencies {

testCompile 'junit:junit:4.8.1'

}

<?xml version="1.0" encoding="UTF-8"?>

<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>pl.gradle</groupId>

<artifactId>simple</artifactId> <packaging>jar</packaging>

<version>1.0-SNAPSHOT</version> <dependencies>

<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId>

<version>4.8.1</version> <scope>test</scope>

</dependency> </dependencies>

<build> <plugins>

<plugin> <groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source>

<target>1.5</target> </configuration>

</plugin> </plugins>

</build></project>

<project name="simple" default="dist" basedir=".">

<property name="src" location="src/main/java" />

<property name="srcTest" location="src/test/java" /><property name="build" location="build" />

<property name="dist" location="${build}/lib" />

<path id="classpath.test">

<pathelement location="libs/junit-4.8.1.jar" /><pathelement location="${srcTest}" />

<pathelement location="${build}/classes" /> <pathelement location="${build}/test-classes" />

</path>

<target name="init"> <mkdir dir="${build}/classes" /> <mkdir dir="${build}/test-classes" />

</target>

<target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}/classes" />

</target>

<target name="testCompile" depends="init"> <javac srcdir="${srcTest}" destdir="${build}/test-classes"> <classpath refid="classpath.test" />

</javac></target>

<target name="test" depends="testCompile"> <junit fork="yes" haltonfailure="yes">

<batchtest fork="yes"> <fileset dir="${srcTest}">

<include name="**/*Test.java" /> <include name="**/Test*.java" />

</fileset> </batchtest> <classpath refid="classpath.test" />

<formatter type="plain"/> </junit>

</target><target name="dist" depends="compile">

<mkdir dir="${dist}" /> <jar jarfile="${dist}/simple.jar" basedir="${build}/classes" />

</target><target name="clean"> <delete dir="${build}" />

</target></project>

Conventionover

configuration

Page 25: Gradle talk, Javarsovia 2010

2010

repositories { mavenCentral()}

More onrepositories

Page 26: Gradle talk, Javarsovia 2010

2010

repositories { mavenCentral() mavenRepo urls: 'http://download.java.net/maven2' flatDir name: 'localRepository', dirs: 'lib''}

More onrepositories

Page 27: Gradle talk, Javarsovia 2010

2010

More onrepositories

// Maven2 layoutsomeroot/[organisation]/[module]/[revision]/[module]-[revision].[ext]

// Typical layout for an ivy repositorysomeroot/[organisation]/[module]/[revision]/[type]s/[artifact].[ext]

//Simple layout (the organization is not used, no nested folders.)someroot/[artifact]-[revision].[ext]

repositories { mavenCentral() mavenRepo urls: 'http://download.java.net/maven2' flatDir name: 'localRepository', dirs: 'lib''}

Page 28: Gradle talk, Javarsovia 2010

2010

apply plugin: 'java'apply plugin: 'maven'

configure(install.repositories.mavenInstaller) { pom.project { version '1.0-Maven' groupId 'myGroup' artifactId 'myArtifact' } }

Maven artifacts upload – local

repo

Page 29: Gradle talk, Javarsovia 2010

2010

apply plugin: 'java'apply plugin: 'maven'

configure(install.repositories.mavenInstaller) { pom.project { version '1.0-Maven' groupId 'myGroup' artifactId 'myArtifact' } }

Maven artifacts upload – local

repo

~/.m2/repository/myGroup/myArtifact/

|-- 1.0-Maven

| |-- myArtifact-1.0-Maven.jar

| `-- myArtifact-1.0-Maven.pom

`-- maven-metadata-local.xml

Page 30: Gradle talk, Javarsovia 2010

2010

configurations { deployerJars}

dependencies { deployerJars "org.apache.maven.wagon:wagon-ssh:1.0-beta-2"}

uploadArchives { repositories.mavenDeployer { configuration = configurations.deployerJars repository(url: "scp://myrepo.com/releases") { authentication(userName: "me", password: "pass") } }}

Maven artifacts upload – remote repo

Page 31: Gradle talk, Javarsovia 2010

2010

Core

Page 32: Gradle talk, Javarsovia 2010

2010

Core - summary

• Very concise build.gradle file– DSL– Convention over configuration

• Configuration is always possible

• Backward compatibility– Respects standards (layout a'la Maven)– Ivy & Maven dependencies and repositories

Page 33: Gradle talk, Javarsovia 2010

2010

Gradle & Maven – dependencies and repositories

• Full backward compatibility• Download from and upload to Maven

repos– Including generation of pom files

• Gradle offers more than Maven– Uses Apache Ivy– Mercury (Maven 3) will be supported

Page 34: Gradle talk, Javarsovia 2010

2010

Gradle – custom logic

• Directly within build script (build.gradle)– Any Groovy code– Can import 3rd party classes

Page 35: Gradle talk, Javarsovia 2010

2010

Gradle – custom logic

• Directly within build script (build.gradle)– Any Groovy code– Can import 3rd party classes

• Custom tasks– build.gradle says ”what”– ”how” described in task class

Page 36: Gradle talk, Javarsovia 2010

2010

Gradle – custom logic

• Directly within build script (build.gradle)– Any Groovy code– Can import 3rd party classes

• Custom tasks– build.gradle says ”what”– ”how” described in task class

• Custom plugins– More powerful than tasks, but still very easy to create– Some shipped with Gradle:

• Java, Groovy, Scala, War, Jetty, Maven, Code Quality, OSGi, Eclipse, Project Report

Page 37: Gradle talk, Javarsovia 2010

2010

Gradle – custom logic

• Directly within build script (build.gradle)– Any Groovy code– Can import 3rd party classes

• Custom tasks– build.gradle says ”what”– ”how” described in task class

• Custom plugins– More powerful than tasks, but still very easy to create– Some shipped with Gradle:

• Java, Groovy, Scala, War, Jetty, Maven, Code Quality, OSGi, Eclipse, Project Report

Page 38: Gradle talk, Javarsovia 2010

2010

public class ReportTask extends DefaultTask {

def FileCollection jars

@TaskAction def createReport() { def text = new StringBuilder() text.append("gradle -v".execute().text) jars.each { text.append("\t- $it.name\n") } println "GENERATING REPORT" new File('build/report.txt') << text }}

Custom logic :”how” described in task class

Page 39: Gradle talk, Javarsovia 2010

2010

import org.gradle.sample.report.ReportTask

configurations { myDependencies}

dependencies { ... myDependencies 'org.jmock:jmock:2.5.1'}

task generateReport(type: ReportTask) { jars = configurations.runtime + configurations.myDependencies}

Custom logic :”what” described in build.gradle

Page 40: Gradle talk, Javarsovia 2010

2010

Gradle – custom logic

Page 41: Gradle talk, Javarsovia 2010

2010

Web UIapply plugin: 'war'

repositories { ...}

dependencies { ...}

Conventionover

configuration

|-- build.gradle

`-- src

`-- main

|-- java

|-- resources

`-- webapp

Page 42: Gradle talk, Javarsovia 2010

2010

Web UIapply plugin: 'war'

repositories { ...}

dependencies { ...}

Conventionover

configuration

:war - Generates a war archive with all the compiled classes, the web-app content and the libraries.

Page 43: Gradle talk, Javarsovia 2010

2010

Web UI:war - Generates a war archive with all the compiled classes, the web-app content and the libraries.

:jettyRun - Uses your files as and where they are and deploys them to Jetty.

:jettyRunWar - Assembles the webapp into a war and deploys it to Jetty.

apply plugin: 'war'apply plugin: 'jetty'

repositories { ...}

dependencies { ...}

Page 44: Gradle talk, Javarsovia 2010

2010

Web UI

Page 45: Gradle talk, Javarsovia 2010

2010

Gradle & Ant – import of build.xml

<project> <target name="hello"> <echo>Hello, from Ant</echo> </target></project>

Page 46: Gradle talk, Javarsovia 2010

2010

Gradle & Ant – import of build.xml

<project> <target name="hello"> <echo>Hello, from Ant</echo> </target></project>

ant.importBuild "build.xml"

task myTask(dependsOn: hello) << { println "depends on hello ant task"}

Page 47: Gradle talk, Javarsovia 2010

2010

Gradle & Ant – import of build.xml

<project> <target name="hello"> <echo>Hello, from Ant</echo> </target></project>

ant.importBuild "build.xml"

task myTask(dependsOn: hello) << { println "depends on hello ant task"}

>gradle myTask:hello[ant:echo] Hello, from Ant:myTaskdepends on hello ant task

Page 48: Gradle talk, Javarsovia 2010

2010

Gradle & Ant – use of Ant tasks

task zip << {

ant.zip(destfile: 'archive.zip') {

fileset(dir: 'src') {

include(name: '**.xml')

exclude(name: '**.java')

}

}

Page 49: Gradle talk, Javarsovia 2010

2010

Gradle & Ant – use of Ant tasks

task zip << {

ant.zip(destfile: 'archive.zip') {

fileset(dir: 'src') {

include(name: '**.xml')

exclude(name: '**.java')

}

}

task dist(type: Zip) {

from 'src/dist‘

from configurations.runtime

into('libs‘)

}

Page 50: Gradle talk, Javarsovia 2010

2010

Gradle & Ant - summary

• Ant targets = Gradle tasks• Import of build.xml• Use of Ant

– ant object available in every build.gradle• AntBuilder used beneath

– some Ant tasks rewritten• for optimization purposes and to be consistent

with other concepts of Gradle

• Gradle = Ant with a boost

Page 51: Gradle talk, Javarsovia 2010

2010

Desktop UI - Groovyapply plugin: 'groovy'

repositories { mavenCentral()}

dependencies { groovy "org.codehaus.groovy:groovy-all:1.7.3"}

Page 52: Gradle talk, Javarsovia 2010

2010

Desktop UI - Groovyapply plugin: 'groovy'

repositories { mavenCentral()}

dependencies { groovy "org.codehaus.groovy:groovy-all:1.7.3"}

task run (dependsOn: build) << { ant.java(classname: 'org.gradle.sample.ui.swing.SwingApp', fork: true, classpath: "${sourceSets.main.runtimeClasspath.asPath}")}

Page 53: Gradle talk, Javarsovia 2010

2010

Desktop UI

Page 54: Gradle talk, Javarsovia 2010

2010

Web & Desktop UI - summary

• Convention over configuration makes things easy

• Jetty plugin available out-of-the-box• Many JVM languages supported

– Java, Groovy, Scala

Page 55: Gradle talk, Javarsovia 2010

2010

Multi-module build

multi|-- build.gradle|-- settings.gradle|-- core| `-- ...`-- ui |-- swing | `-- ... `-- web `-- ...

Page 56: Gradle talk, Javarsovia 2010

2010

Multi-module build

multi|-- build.gradle|-- settings.gradle|-- core| `-- ...|-- frontend| |-- swing| | `-- ...| |-- android| | `-- ...| `-- web| `-- ...`-- backend `-- swing `-- ...

Page 57: Gradle talk, Javarsovia 2010

2010

Multi-module build

multi|-- build.gradle|-- settings.gradle|-- core| `-- ...`-- ui |-- swing | `-- ... `-- web `-- ...

include "core", "ui:swing", "ui:web"

Page 58: Gradle talk, Javarsovia 2010

2010

Multi-module build

Page 59: Gradle talk, Javarsovia 2010

2010

Multi-module build – how many build.gradle files?

multi|-- build.gradle|-- settings.gradle|-- core| `-- ...`-- ui |-- swing | `-- ... `-- web `-- ...

multi|-- build.gradle|-- settings.gradle|-- core| |-- build.gradle| `-- ...`-- ui |-- swing | |-- build.gradle | `-- ... `-- web | |-- build.gradle `-- ...

configure(:core) { ...}

...

Page 60: Gradle talk, Javarsovia 2010

2010

Multi-module build - summary

• Layout – its up to you• Number of build.gradle files – you decide• Smart (partial) builds• Project treated as tasks

– You can depend on them

Page 61: Gradle talk, Javarsovia 2010

2010

Page 62: Gradle talk, Javarsovia 2010

2010

Page 63: Gradle talk, Javarsovia 2010

2010

Page 64: Gradle talk, Javarsovia 2010

2010

Page 65: Gradle talk, Javarsovia 2010

2010

Page 66: Gradle talk, Javarsovia 2010

2010

Page 67: Gradle talk, Javarsovia 2010

2010

Page 68: Gradle talk, Javarsovia 2010

2010

Use

Gradlefor your next project

Page 69: Gradle talk, Javarsovia 2010

2010

Links

• http://gradle.org• http://gradle.biz• http://docs.codehaus.org/display/GRADLE/

Cookbook• http://docs.codehaus.org/display/GRADLE/

Releases

Page 70: Gradle talk, Javarsovia 2010

2010

Thank you

Tomek Kaczanowskihttp://kaczanowscy.pl/tomek

Would be great if you could provide some feedback [email protected]