Gradle Release Notes

Version 0.9

  1. New and Noteworthy
  2. Migrating from 0.8
  3. Fixed Jira Issues

New and Noteworthy

Incremental builds

Gradle will now skip a task if its input files have not changed since the task last ran. It will do this for all built-in tasks and for any custom tasks that you write. It can even do this for the ad hoc tasks that you define in your build script. Writing builds which are both large and performant has never been easier.

We've put a lot of effort into making sure that incremental builds are reliable. No more running clean before you run a build. Gradle will take care of things such as cleaning up old classes and resources, and recompiling dependent classes when source files change. This means no more running stale tests or building archives that contain the stale files.

See the user guide for some details about how to use this for your tasks.

Simple build composition using scripts

You can now easily apply any number of build scripts to a project. This allows you to do lots of useful things: you can split a large build script into smaller pieces, you can use it to apply common configuration to multiple projects, or to multiple builds across your organization. You can even implement plugins using scripts.

Scripts can be applied from any URL, which means you can share scripts using HTTP.

You can apply scripts to any arbitrary object, so you can use them to configure any object, such as tasks, repositories or your own custom build objects.

See the user guide

The Gradle Daemon

This release includes the experimental Gradle daemon. The daemon runs in the background, and performs builds. This way it avoids the startup costs.

See the user guide

Gradle build language reference guide

We've added a reference guide for the Gradle build language. This reference guide documents all the properties, methods and script blocks for the main classes that make up the Gradle DSL, along with all of the task implementations.

See http://gradle.org/0.9/docs/dsl/index.html

Gradle Plugin for IDEA

A plugin for IDEA is now available which allows you to explore and run Gradle builds from within IDEA. The plugin is available via the plugin manager in IDEA.

IDE Plugins

We've add an 'idea' plugin which generates the project files for IDEA, and we've rewritten the 'eclipse' plugin. Both plugins automatically discover and download the source and javadoc JARs for all your dependencies. And both plugins offer lots of hooks for flexible configuration.

See the idea plugin and eclipse plugin for details.

New archive task API

The archive tasks now share the same API as the copy task, based on the powerful CopySpec interface. This means that all the capabilities you can use when copying are now available when you create an archive. This includes being able to filter the contents or rename certain files as they are being added to the archive. You can share CopySpecs between tasks, so you can, for example, use the same definition to generate a WAR and an exploded WAR. Or ZIP, TAR and exploded distributions.

In addition, the Jar and War tasks have been much simplified, so that it is much easier to define the contents of the META-INF and WEB-INF directories. The Jar and War tasks are now easily used in builds which don't use the Java or War plugins.

Manifest generation is also much improved. You can share manifest definitions between tasks, import from existing manifest, or merge manifests together in flexible ways.

See working with files and java plugin

Testing

Parallel test execution

The Test task now supports parallel test execution. Enabling this is as easy as setting the maxParallelForks property. So now, you can easily take advantage of those extra cores that weren't doing anything, to speed up your test execution.

Execute a single test

You can run Gradle with \-Dtest.single=SomeClassName to run a single test class.

Maximum tests per process

You can also specify the maximum number of test classes to execute in a forked test process. The process is restarted when the limit is reached. Fork modes 'per test' and 'once' are just special cases of this. This provides an efficient alternative to adding more and more heap space for your test process, without the performance hit of forking per test.

Test listeners

Finally, you can now register a listener to receive notification as tests execute, to do custom reporting or some other test result analysis.

These test features work equally well for JUnit and TestNG test suites.

See the user guide

Antlr support

The new Antlr plugin adds support for generating source from Antlr grammars.

See the user guide

Announce plugin

The new Announce plugin adds support for providing notifications from your build to various destinations, such as twitter, or locally using snarl, libnotify, or growl.

See the user guide

Maven POM generation

You can change or extend what Gradle adds to generated Maven POMs, using exactly the same syntax that polygot Maven uses.

File handling

More useful method have been added to various file handling APIs. For example, you can now obtain the contents of a ZIP file as a file tree, which you can pass to any task which understands file collections (pretty much all of them). The file DSL is now available in all scripts which Gradle executes, not just build scripts.

See the user guide

New tasks

We've added a Sync task, which extends the Copy task to delete any files from the destination directory which were not part of the copy operation. This is useful for things like installing your distribution, or for maintaining a copy of your dependencies in a particular directory.

The general purpose Delete task replaces the specific Clean and EclipseClean tasks.

There's also a new GradleBuild task, which you can use to execute another Gradle build from within your build. We've added an Exec task to execute arbitrary commands, and a JavaExec task to execute arbitrary Java applications.

See the DSL reference

Build profiler

A profiler is now built into Gradle, to help you profile your builds if you have performance problems.

See the user guide

Writing plugins

Added ProjectBuilder to help you test your custom task and plugin implementations.

See the user guide

Updated dependencies

Build scripts are now executed using Groovy 1.7.6 and Ant 1.8.1

Performance

Migrating from 0.8

Gradle 0.9 Breaking Changes

Fixed Jira Issues

0.9 Breaking Changes

Have a look at Gradle 0.9 Release Notes for more information about the new features in this release

  1. Build Scripts
    1. Updated to Groovy 1.7.3
    2. Using plugins
  2. Wrapper
  3. Other Changes
  4. API Changes

Build Scripts

Updated to Groovy 1.7.3

Build scripts are now executed using Groovy 1.7.3. This should not cause any problems for most build scripts.

Using plugins

The usePlugin() method has been deprecated. Instead, you should use the apply() method.

0.8 0.9
{code}usePlugin 'java'
{code}apply plugin: 'java'

apply plugin: MyPluginClass
// or
apply {
plugin 'java'
plugin MyPluginClass}

Task action closures

The actions passed to Task.doFirst() and Task.doLast(), which includes those added using the << operator, now delegate to the task first, and then the owner of the closure. Previously, these closure would delegate to the owner first, then the project of the task. These changes make the behaviour of these closures consistent with the behaviour of other closures, such as task configuration closures. For most cases, existing task action closures will continue to work unmodified. The following properties and methods will now refer to the task, rather than the project: Also, be aware that when you set a dynamic property in the task action closure, it will now set the property on the task, rather than the project.
0.8 0.9

task show << {
   println name
   println path
   someProp = 'value'
}        
      


task show << {
   println project.name
   println project.path
   project.someProp = 'value'
}        
      

Task onlyIf()

Each call to Task.onlyIf() now adds a predicate which must evaluate to true for the task to be executed. Previously, calling this method would replace any previously specified predicate. You can use Task.setOnlyIf() to get the old behaviour.

Project buildDirName

The Project.buildDirName property has been deprecated. It has been replaced by the buildDir property:
0.8 0.9


buildDirName = 'someDir'        
      

buildDir = 'someDir'        
      

Tasks

Archive tasks

The Archive tasks now share a common API with the Copy task. This affects the Zip, Tar, Jar and War tasks. * The fileSet() method has been replaced with the from() method:
0.8 0.9


zip {
    fileSet(dir: 'somedir') {
        include '**/*.xml'
    }
}        
      

zip {
    from('somedir') {
        include '**/*.xml'
    }
}        
      
* The zipFileSet() method has been replaced with the from() and into() methods. The equivalent of prefix, fileMode and dirMode are supported. There is no replacement for fullPath.
0.8 0.9


zip {
    zipFileSet(dir: 'somedir', prefix: 'bin', filemode: '755') {
        include '**/*.sh'
    }
}        
      

zip {
    from('somedir') {
        into 'bin'
        fileMode = 0755
        include '**/*.sh'
    }
}
// or
zip {
    into('bin') {
        from 'somedir'
        fileMode = 0755
        include '**/*.xml'
    }
}        
      
* The tarFileSet() method has been replaced by the from() and into() methods, as for zipFileSet(). There are no replacements for userName, group, uid or gid. * The customName property has been merged into the archiveName property
0.8 0.9

zip {
    customName = 'some.zip'
}        
      

zip {
    archiveName = 'some.zip'
}        
      
* The resourceCollections() method has been replaced by the from() method.
0.8 0.9


zip {
    resourceCollections fileTree('somedir')
}        
      


zip {
    from fileTree('somedir')
}        
      
* The merge() and mergeGroup() methods have been removed. You can use Project.zipTree() and Project.tarTree() to achieve the same thing:
0.8 0.9


zip {
    merge 'some-file.zip'
    mergeGroup('some-dir') {
        include '*.zip'
    }
}        
      


zip {
    from zipTree('some-file.zip')
    fileTree(dir: 'some-dir', includes ['*.zip']).each {
        from zipTree(it)
    }
}        
      

Jar task

In addition to the changes listed above, the following changes have been made to the Jar task: * The metaInfResourceCollections property has been replaced by the metaInf() \{...\} method. This operates the same as if a call to into('META-INF') \{...\} was made:
0.8 0.9

jar {
    metaInfResourceCollections = [fileTree('src/main/META-INF')]
}        
      

jar {
    metaInf {
        from 'src/main/META-INF'
    }
}        
      

War task

TBD

Copy task

Test task

JUnit Tests

* The forkMode property has been replaced by a forkEvery property.
0.8 0.9


test {
    options.fork.forkMode = ForkMode.PER_TEST
    options.fork.forkMode = FrokMode.ONCE
}        
      


test {
    forkEvery = 1 // or any value > 0
    forkEvery = null // this is the default value
}        
      
* A number of properties have been moved from JUnitOptions to Test
0.8 0.9


test {
    options.systemProperties['someProp'] = 'value'
    options.environment['SOME_VAR'] = 'value'
    options.fork.jvmArgs = ['-ea', '-Xmx256m']
    options.fork.dir = file('someDir')
    options.fork.jvm = 'somewhere/bin/java'
    options.fork.maxMemory = '1024m'
    options.fork.bootstrapClasspath = someClassPath
}        
      


test {
    systemProperties['someProp'] = 'value'
    environment['SOME_VAR'] = 'value'
    jvmArgs = ['-ea', '-Xmx256m']
    workingDir = file('someDir')
    executable = 'somewhere/bin/java'
    maxHeapSize = '1024m'
    bootstrapClasspath = someClassPath
}        
      
0.8 0.9


test {
    options.cloneVm = true
    options.cloneVm = false
    options.newEnvironment = false
    options.newEnvironment = true
}        
      


test {
    systemProperties = System.properties
    systemProperties = [:] // the default
    environment = System.env // the default
    environment = [:]
}         
      

TestNG Tests

* A number of properties have moved from TestNGOptions to Test
0.8 0.9


test {
    useTestNG()
    options.systemProperties['someProp'] = 'value'
    options.environment['SOME_VAR'] = 'value'
    options.jvmArgs = ['-ea', '-Xmx256m']
    options.jvm = 'somewhere/bin/java'
    options.enableAssert = true
}        
      


test {
    useTestNG()
    systemProperties['someProp'] = 'value'
    environment['SOME_VAR'] = 'value'
    jvmArgs = ['-ea', '-Xmx256m']
    executable = 'somewhere/bin/java'
    enableAssertions = true
}        
      
* The skippedProperty, dumpCommand, suiteRunnerClass properties have been removed from TestNGOptions.

Clean task

* The Clean task has been replaced by the Delete task.

EclipseClean task

* The EclipseClean task has been replaced by the Delete task.

Plugin Authoring

* The Plugin interface has changed, so that it can target any time of object. The signature of Plugin.use() has also changed to reflect this:
0.8 0.9


public class MyPlugin implements Plugin {
    void use(Project project, ProjectPluginsContainer projectPluginsHandler) {
        // do some stuff to project
    }
}        
      


public class MyPlugin implements Plugin {
    void apply(Project project) {
        // do some stuff to project
    }
}        
      
0.8 0.9
$GRADLE_HOME/plugin.properties

myplugin=com.something.MyPluginImpl        
      
myplugin.jar!META-INF/gradle-plugins/myplugin.properties

implementation-class=com.something.MyPluginImpl        
      

Wrapper

Other Changes

API Changes