Gradle Release Notes

Version 2.2

Gradle 2.2 delivers some nice general features and improvements, as well as profound new capabilities for dependency management.

The addition of arbitrary “Component Selection Rules” and the modelling of module “replacement” continues to push the state of the art in JVM dependency management. Selection rules allow extremely fine grained, custom, conflict resolution strategies. Support for declaring module replacements allows Gradle to consider modules that have different identities but that conflict in some way during conflict resolution. This can be used to avoid ending up with duplicate copies of libraries at different versions due to their published coordinates changing over time or due to merging into other libraries entirely.

Support for the SonarQube code quality management platform has significantly improved in this release. The Sonar Runner no longer runs in the build process, which allows more control over its execution (e.g. memory settings) and the use of arbitrary versions of the Sonar Runner. This will allow leveraging of new Sonar features without updates to the plugin and more control over how Gradle integrates with Sonar.

The new support for “text resources”, added to the code quality plugins (e.g. the Checkstyle plugin), opens up new possibilities for sharing configuration/settings for code quality checks. More generally, support for “text resources” opens up new possibilities for obtaining and/or generating text to be used in the build process, typically as a file. While only in use by the code quality plugins at this release, this new mechanism will be leveraged by other tasks and plugins in future versions of Gradle.

Gradle 2.1 previously set the high watermark for contributions to Gradle with contributions by 18 different contributors. This release raises that high watermark to contributions by 23 different contributors. Thank you to all who have contributed and helped to make Gradle an even better build system.

We hope you enjoy Gradle 2.2.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Component Selection Rules incubating feature

Fine tuning the dependency resolution process is even more powerful now with the use of component selection rules. These allow custom rules to be applied whenever multiple versions of a component are being evaluated. Using such rules, one can explicitly reject a version that might otherwise be accepted by the default version matching strategy.

configurations {
    conf {
        resolutionStrategy {
            componentSelection {
                // Accept the newest version that matches the dynamic selector
                // but does not end with "-experimental".
                all { ComponentSelection selection ->
                    if (selection.candidate.group == 'org.sample'
                            && selection.candidate.name == 'api'
                            && selection.candidate.version.endsWith('-experimental')) {
                        selection.reject("rejecting experimental")
                    }
                }

                // Rules can consider component metadata as well
                // Accept the highest version with a branch of 'testing' or a status of 'milestone'
                all { ComponentSelection selection, IvyModuleDescriptor descriptor, ComponentMetadata metadata ->
                    if (descriptor.branch != 'testing' && metadata.status != 'milestone') {
                        selection.reject("does not match branch or status")
                    }
                }

                // Rules can target specific modules
                // Reject the 1.1 version of org.sample:api
                withModule("org.sample:api") { ComponentSelection selection ->
                    if (selection.candidate.version == "1.1") {
                        selection.reject("known bad version")
                    }
                }
            }
        }
    }
}

dependencies {
    conf "org.sample:api:1.+"
}

See the User Guide section on component selection rules for further information.

Declaring module replacements incubating feature

It is now possible to declare that a certain module has been replaced by some other. An example of this happening in the real world is the replacement of the Google Collections project by Google Guava. By making Gradle aware that this happened, Gradle can consider that these modules are the same thing when resolving conflicts in the dependency graph. Another common example of this phenomenon is when a module changes its group or name. Examples of such changes are org.jboss.netty -> io.netty, spring -> spring-core and there are many more.

Module replacement declarations can ship with as part of custom Gradle plugins and enable stronger and smarter dependency resolution for all Gradle-powered projects in the enterprise.

This new incubating feature is described in detail in the User Guide.

dependencies {
  modules {
    module("com.google.collections:google-collections") {
      replacedBy("com.google.guava:guava")
    }
  }
}

Sonar Runner plugin improvements

The Sonar Runner Plugin has been improved to fork the Sonar Runner process, whereas in previous Gradle versions the runner was executed within the build process. This was problematic is it made controlling the environment (e.g. JVM memory settings) for the runner difficult and meant the runner could destabilize the build process. Importantly, because the Sonar Runner process is now forked, the version of Sonar Runner to use can now be configured in the build allowing choice of the version of Sonar Runner to use.

The sonar-runner plugin defaults to using version 2.3 of the runner. Upgrading to a later version is now simple:

apply plugin: "sonar-runner"

sonarRunner {
  toolVersion = "2.4"

  // Fine grained control over the runner process
  forkOptions {
    maxHeapSize = '1024m'
  }
}

This feature was contributed by Andrea Panattoni.

Native language cross-compilation improvements incubating feature

Various improvements were made to the ability to configure a native tool chain from cross-compilation. These improvements should make easier to use Gradle to compile for a target platform other than the host.

These improvements include:

model {
        toolChains {
            gcc(Gcc) {
                eachPlatform { tc ->
                    if (tc.platform.name == "arm") {
                        cCompiler.executable = 'gcc-arm'
                    }
                }
            }
        }
    }

Support for building x64 binaries on Windows using GCC incubating feature

Previous versions of Gradle have supported building x86 binaries using GCC on Windows. This Gradle release adds initial support for building x64 binaries using GCC on Windows.

Specify version control system for IntelliJ IDEA

When using the idea plugin, it is now possible to specify the version control system to configure IDEA to use when importing the project.

apply plugin: "idea"

idea {
  project {
    vcs = "Git"
  }
}

Note: This setting is only respected when the project is opened in IDEA using the .ipr (and associated) files generated by the ./gradlew idea task. It is not respected when the project is imported into IDEA using IDEA's import feature.

This feature was contributed by Kallin Nagelberg.

Specify location of local maven repository independently

The location of the local Maven repository can now be controlled by setting the system property maven.repo.local to the absolute path to the repo. This has been added for parity with Maven itself. This can be used to isolate the maven local repository for a particular build, without changing the location of the ~/.m2/settings.xml which may contain information to be shared by all builds.

This feature was contributed by Christoph Gritschenberger.

Compatibility with OpenShift

The OpenShift PaaS environment uses a proprietary mechanism for discovering the binding address of the network interface. Gradle requires this information for inter process communication. Support has been added for this environment which now makes it possible to use Gradle with OpenShift.

This feature was contributed by Colin Findlay.

Support for renaming imported Ant targets

When importing an Ant build it is now possible to specify an alternative name for tasks that corresponds to the targets of the imported Ant build. This can be used to resolve naming collisions between Ant targets and existing Gradle tasks (GRADLE-771).

To do so, supply a transformer to the [ant.importBuild()] method that supplies the alternative name.

apply plugin: "java" // adds 'clean' task

ant.importBuild("build.xml") {
    it == "clean" ? "ant-clean" : it
}

The above example avoids a name collision with the clean task. See the section on importing Ant builds in the Gradle Userguide for more information.

This feature was contributed by Paul Watson.

Sharing configuration files across builds incubating feature

In previous Gradle versions, sharing external configuration files across builds (e.g. to enforce code quality standards) was difficult. To support this use case, a new TextResource abstraction was introduced.

TextResources are created using factory methods provided by project.resources.text. They can be backed by various sources such as inline strings, local text files, or archives containing text files. A TextResource backed by an archive can then be shared across builds by publishing and resolving the archive from a binary repository, benefiting from Gradle's standard dependency management features (e.g. dependency caching).

Gradle's code quality plugins and tasks are the first to support TextResource. The following example shows how a Checkstyle configuration file can be sourced from different locations:

apply plugin: "checkstyle"

configurations {
    checkstyleConfig
}

dependencies {
    // a Jar/Zip/Tar archive containing one or more Checkstyle configuration files,
    // shared via a binary repository
    checkstyleConfig "com.company:checkstyle-config:1.0@zip"
}

checkstyle { // affects all Checkstyle tasks
    // sourced from inline string
    config = resources.text.fromString("""<module name="Checker">...</module>""")
    // sourced from local file
    config = resources.text.fromFile("path/to/file.txt")
    // sourced from a task that produces a single file (and declares it as output)
    config = resources.text.fromFile(someTask)
    // sourced from shared archive
    config = resources.text.fromArchiveEntry(configurations.checkstyleConfig, "path/to/archive/entry.txt")
}

Over time, TextResource will be leveraged by more existing and new Gradle APIs.

Plugin to package and publish plugins

The submission process for Gradle plugins is currently a work in progress, and upcoming versions of Gradle will provide a fully automated publishing process for plugins. Since we are not quite there yet, we are happy that there is the 3rd-party plugindev plugin that highly facilitates packaging and publishing of plugins. Thus, for the time being, we recommend to use the plugindev plugin. You can learn here about how to use it.

plugins {
    id 'nu.studer.plugindev' version '1.0.3'
}

group = 'org.example'
version = '0.0.1.DEV'

plugindev {
    pluginImplementationClass 'org.example.gradle.foo.FooPlugin'
    pluginDescription 'Gradle plugin that does foo.'
    pluginLicenses 'Apache-2.0'
    pluginTags 'gradle', 'plugin', 'foo'
    authorId 'johnsmith'
    authorName 'John Smith'
    authorEmail 'john@smith.org'
    projectUrl 'https://github.com/johnsmith/gradle-foo-plugin'
    projectInceptionYear '2014'
    done()
}

bintray {
    user = "$BINTRAY_USER"
    key = "$BINTRAY_API_KEY"
    pkg.repo = 'gradle-plugins'
}

Fixed issues

Deprecations

Features that have become superseded or irrelevant due to the natural evolution of Gradle become deprecated, and scheduled to be removed in the next major Gradle version (Gradle 3.0). See the User guide section on the “Feature Lifecycle” for more information.

The following are the newly deprecated items in this Gradle release. If you have concerns about a deprecation, please raise it via the Gradle Forums.

Modifying a parent configuration of a configuration that has been resolved

In previous Gradle releases, it was possible to modify a configuration whose child has been resolved. This, however, leads to confusing behaviour because each configuration is resolved once and the result reused. This means that the changes made to the parent will never be used by the child configuration.

This behaviour is now deprecated and will become an error in Gradle 3.0.

Potential breaking changes

filesMatching used in CopySpec now matches against source path rather than destination path

In the example below, both filesMatching blocks will now match against the source path of the files under from. In previous versions of Gradle, the second filesMatching block would match against the destination path that was set by executing the first block.

task copy(type: Copy) {
    from 'from'
    into 'dest'
    filesMatching ('**/*.txt') {
        path = path + '.template'
    }
    filesMatching ('**/*.template') { // will not match the files from the first block anymore
        path = path.replace('template', 'concrete')
    }
}

Manually added AntTarget tasks no longer respect target dependencies

The org.gradle.api.tasks.ant.AntTarget task implementation adapts a target from an Ant build to a Gradle task and is used when Gradle imports an Ant build.

In previous Gradle versions, it was somewhat possible to manually add tasks of this type and wire them to Ant targets manually. However, this was not recommended and can produce surprising and incorrect behaviour. Instead, the ant.importBuild() method should be used to import Ant build and to run Ant targets.

As of Gradle 2.2, manually added AntTarget tasks no longer honor target dependencies. Tasks created as a result of ant.importBuild() (i.e. the recommended practice) are unaffected and will continue to work.

Sonar Runner Plugin changes

The Sonar Runner plugin now forks a new JVM to analyze the project. Projects using the Sonar Runner Plugin should consider setting explicitly the memory settings for the runner process.

Existing users of the sonar-runner plugin may have increased the memory allocation to the Gradle process to facilitate the Sonar Runner. This can now be reduced.

Additionally, the plugin previously mandated the use of version 2.0 of the Sonar Runner. The default version is now 2.3 and it is configurable. If you require the previous default of 2.0, you can specify this version via the project extension.

sonarRunner {
  toolVersion = '2.0'
}

Publishing plugins and Native Language Support plugins changes

In previous Gradle versions it was possible to use afterEvaluate {} blocks to configure tasks added to the project by "maven-publish", "ivy-publish" and Native Language Support plugins. These tasks are now created after execution of afterEvaluate {} blocks. This change was necessary to continue improving the new model configuration. Please use model {} blocks instead for that purpose, e.g.:

model {
    tasks.generatePomFileForMavenJavaPublication {
        dependsOn 'someOtherTask'
    }
}

CodeNarc plugin Groovy version changes

The version of Groovy that the CodeNarc plugin uses while analyzing Groovy source code has changed in this Gradle release. Previously, the version of Groovy that Gradle ships with was used. Now, the version of Groovy that the CodeNarc tool declares as a dependency is used.

The CodeNarc implementation used by the CodeNarc plugin is defined by the codenarc dependency configuration, which defaults to containing the dependency "org.codenarc:CodeNarc:0.21". This configuration is expected to provide all of CodeNarc's runtime dependencies, including the Groovy runtime (which it does by default as the CodeNarc dependency depends on "org.codehaus.groovy:groovy-all:1.7.5"). This should have no impact on users of the CodeNarc plugin. Upon first use of the CodeNarc plugin with Gradle 2.1, you may see Gradle downloading a Groovy implementation for use with the CodeNarc plugin.

Please note that any generally applied dependency rules targeted at Groovy (e.g. changing groovy-all to groovy-core or similar) will now affect the CodeNarc plugin whereas they did not previously.

Change of package names for sonar-runner plugin

The classes of the (incubating) Sonar Runner Plugin have moved from the package org.gradle.api.sonar.runner to org.gradle.sonar.runner.

If you were depending on these classes explicitly, you will need to update the reference.

Changes to incubating native language support

Changes to incubating JVM-component plugins and language support

Using convention mapping for code quality tasks/extensions

Using the internal convention mapping feature for one of the following properties will no longer have an effect:

Configuring code quality tasks/extensions with File objects representing relative paths

A File object that represents a relative path and is used to configure one of the following properties will now be interpreted relative to the current project, rather than relative to the current working directory of the Gradle process:

Note that this only affects files created with new File("relative/path") (which is not recommended), but not files created with project.file("relative/path").

External contributions

We would like to thank the following community members for making contributions to this release of Gradle.

We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.

Known issues

Known issues are problems that were discovered post release that are directly related to changes made in this release.