Gradle Release Notes

Version 2.0

Gradle 2.0 is an important milestone in the evolution of Gradle. As explained in the Gradle 2.0 announcement, the change in major version number signals a new backwards compatibility baseline. Many deprecated features and API have been removed in this release, allowing the development team to simplify the codebase and implement new functionality. The “Potential Breaking Changes” section of these release notes list all of the breaking changes that have been made and all Gradle users are strongly encouraged to read the list.

Gradle has matured considerably in the evolution from 1.0 to 2.0. It is more performant and is more memory efficient, particularly for large builds. Performance optimization is a persistent area of investment and work, with further optimizations to come during the 2.x stream. Performance, in all aspects, is critically important to a build system.

In addition to the breaking changes, it's business as usual with the steady evolution of Gradle via new and refined API and features.

The move to Groovy 2.3.2 from Groovy 1.8 brings with it all of the new features added to Groovy in this time. There is now a public API for resolving “source” and “javadoc” JARs for JVM library components. The exposing of Ivy “Extra Info” attributes enables a new class of advanced dependency management use cases. It is now possible to use the SFTP protocol for dependency consumption without using custom Ivy resolvers. Maven POM profile support has also been improved through support for profile activation through absence of a system property. There are also other refinements and improvements detailed below, including improvements to Gradle's support for building native projects.

We hope you enjoy Gradle 2.0 and the coming releases in the 2.x stream.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Updated to Groovy 2.3.2

Gradle now uses Groovy 2.3.2 to compile and run build scripts and plugins. Gradle 1.12 (the last release in the Gradle 1.x stream) used Groovy 1.8.6. This means that build scripts, and plugins/tasks implemented in Groovy can now use the latest Groovy features.

For information on what's new in Groovy, please check the Groovy project site.

Support for Java 8

Running Gradle with Java 8 is now tested for and supported. Java 8 is a substantial update with many substantial changes, as such some tools used by your builds may not be fully compatible yet. For example, Scala's support for Java 8 is still experimental.

A regression within the Java 8 JRE has been identified that causes Gradle to appear to hang for a short amount of time at the end of a non-daemon build on Mac OS X and Linux. Windows users, and users using the Gradle Daemon are unaffected. The Java 8 team are aware of this issue and it will be addressed a future release of Java 8.

In order to support executing Gradle with Java 8, support for Java 1.5 had to be removed. For more on the detail of why this was necessary, please see this forum post.

New API for resolving source and javadoc artifacts incubating feature

Gradle 2.0 introduces a new, incubating, API for resolving component artifacts. With this addition, Gradle now offers separate dedicated APIs for resolving components and artifacts. The entry point to the new 'artifact query' API is dependencies.createArtifactResolutionQuery().

Presently, this feature is limited to the resolution of SourcesArtifact and JavadocArtifact artifacts for JvmLibrary components. Over time this will be expanded to allow querying of other component and artifact types.

For example, to get the source artifacts for all 'compile' dependencies:

task resolveSources << {
    def componentIds = configurations.compile.incoming.resolutionResult.allDependencies.collect { it.selected.id }

    def result = dependencies.createArtifactResolutionQuery()
                      .forComponents(componentIds)
                      .withArtifacts(JvmLibrary, SourcesArtifact, JavadocArtifact)
                      .execute()

    for (component in result.resolvedComponents) {
        component.getArtifacts(SourcesArtifact).each { println "Source artifact for ${component.id}: ${it.file}" }
    }
}

For an example usage of the new API, see the DSL Reference.

Access Ivy extra info from component metadata rules incubating feature

It's now possible to access Ivy extra info from component metadata rules. Roughly speaking, Ivy extra info is a set of user-defined key-value pairs published in the Ivy module descriptor. Rules wishing to access the extra info need to specify a parameter of type IvyModuleMetadata.

Here is an example:

dependencies {
  components {
    eachComponent { component, IvyModuleMetadata ivyMetadata ->
      def deprecated = ivyMetadata.extraInfo["deprecated"]?.asBoolean()
      if (deprecated) {
        throw new GradleException("Component $component is deprecated. This project can not use deprecated components")
      }
    }
  }
}

Collaborate with plugins via plugins.withId() incubating feature

It is common to the need to perform some configuration only if a particular plugin has been applied. The standard approach for doing this to date has been to use the plugins.withType(Class) method, which requires the class object of the implementing plugin…

import com.my.custom.InterestingPlugin

plugins.withType(InterestingPlugin) { 
  // perform some configuration after the “interesting” plugin has been applied if it ever is
}

The new plugins.withId(String) method makes this more convenient by allowing the ID of the plugin to be used instead of the implementing class…

plugins.withId("interesting") {
  // perform some configuration after the “interesting” plugin has been applied if it ever is
}

The withId() method is now the preferred mechanism for configuration conditional on the presence of a plugin.

Support for Ivy and Maven repositories with SFTP scheme

In addition to file, http and https, Ivy and Maven repositories now also support the sftp transport scheme. Currently, authentication with the SFTP server supports only username and password credentials.

Ivy dependencies can be consumed via SFTP by specifying it as the repo protocol…

apply plugin: 'java'

repositories {
    ivy {
        url 'sftp://127.0.0.1:22/repo'
        credentials {
            username 'sftp'
            password 'sftp'
        }
    }
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.1'
}

SFTP can also be used when publishing as an Ivy module…

apply plugin: 'java'
apply plugin: 'ivy-publish'

version = '2'
group = 'org.group.name'

publishing {
    repositories {
        ivy {
            url 'sftp://127.0.0.1:22/repo'
            credentials {
                username 'sftp'
                password 'sftp'
            }
        }
    }
    publications {
        ivy(IvyPublication) {
            from components.java
        }
    }
}

Resolving dependencies from a SFTP server with Maven works in a similar fashion…

apply plugin: 'java'

repositories {
    maven {
        url 'sftp://127.0.0.1:22/repo'
        credentials {
            username 'sftp'
            password 'sftp'
        }
    }
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.1'
}

Publishing via SFTP as a Maven module is not supported at this time.

This feature was contributed by Marcin Erdmann.

Apache Maven POM profile activation based on absence of system property

Gradle 1.12 improved Maven interoperability by supporting POM profiles that are active by default. In Gradle 2.0, POM profiles that are activated by absence of a system property are now respected.

<project>
    ...
    <profiles>
        <profile>
            <id>profile-1</id>
            <property>
                <name>!env</name>
            </property>
        </profile>
    </profiles>
</project>

Fine grained control of arguments passed to native tools incubating feature

The new withArguments() method available on the command line tools of a toolchain allows complete control over the arguments passed to the tool, after Gradle has populated the argument list based on the build model.

apply plugin:'cpp'

model {
    toolChains {
        visualCpp(VisualCpp) {
            cppCompiler.withArguments { List<String> args ->
                args << "-DFRENCH"
            }
        }
        clang(Clang){
            cCompiler.withArguments { List<String> args ->
                Collections.replaceAll(args, "CUSTOM", "-DFRENCH")
            }
            linker.withArguments { List<String> args ->
                args.remove "CUSTOM"
            }
            staticLibArchiver.withArguments { List<String> args ->
                args.remove "CUSTOM"
            }
        }
    }
}

This allows for greater flexibility and use of edge tool features.

Simplified support for native cross compilation and custom platforms (GCC based toolchains) incubating feature

It's now a lot easier to define a target native platform and how to use GCC to build for it. Instead of implementing an interface you can describe a target platform and its configuration in the Gradle DSL.

When declaring a toolchain, the targeted platforms can be configured directly in the toolChain model.

model {
  toolChains {
    gcc(Gcc) {
      target("arm") {
        cppCompiler.executable = "custom-gcc"
        cppCompiler.withArguments { args ->
          args << "-m32"
        }
        linker.withArguments { args ->
          args << "-m32"
        }
      }
      target("sparc") {
      }
    }
    platforms {
      arm {
        architecture "arm"
      }
      sparc {
        architecture "sparc"
      }
    }
  }
}

The User Guide contains more details on how to configure Gcc compatible toolchains for cross compilation.

New 'ivy' layout support for Ivy repositories incubating feature

When consuming from or publishing to an Ivy repository, a layout must be specified that describes how artifacts are organized within that repository.

In addition to the 'gradle' (default) and 'maven' layouts, you can now specify the 'ivy' layout, which is the default ivy artifact and metadata patterns.

repositories {
  ivy {
    url 'http://my.server/repo'
      layout 'ivy'
    }
  }
}

See the User Guide and the DSL Reference for more detail on how to use named layouts.

This feature was contributed by Ben McCann.

Default versions of code quality tools updated

The code quality plugins now use the latest version of the corresponding tool as of the Gradle 2.0 release.

The new versions are:

To revert back to the old version, or to use any different version, you can use the appropriate toolVersion property.

pmd {
  toolVersion = '4.3'
}

Tooling API improvements

The Gradle tooling API allows you to inspect a Gradle build and extract useful information about that build. The GradleProject tooling API model now has a buildDirectory property to provide access to the project's build output directory.

Fixed issues

Potential breaking changes

The Gradle 2.0 release contains many breaking changes, as it is a major version number change and the setting of a new compatibility baseline.

Upgraded to Groovy 2.3.2

Gradle now uses Groovy 2.3.2 to compile and run scripts and plugins.

Generally, Groovy is backwards compatible. However, this change may require that you recompile some plugins and may also require some source changes. It is not guaranteed that Groovy based plugins built with Gradle 1.x will work with Gradle 2.x, but most will.

Can no longer run Gradle using Java 5

Due to the upgrade to Groovy 2.3.2, Gradle can no longer be run using Java 5. It is still possible to build Java projects for Java 5 by running with Java 6 or higher, but configuring compilation and test execution to use a different JDK.

For more on the detail of why this was necessary, please see this forum post.

Upgrades to code quality tool default versions

As mentioned in “New and Noteworthy”, the default versions of all code quality tools have been updated. Generally, these tools are backwards compatible.

Custom TestNG listeners are applied before Gradle's listeners

This change is unlikely to affect any custom listeners, but is mentioned for completeness.

Support for reading or changing file permissions on certain platforms with Java 6

Gradle previously supported file permissions on Solaris and on Linux ia-64 using Java 6. This support has been removed. You will receive a warning when attempting to use file permissions on these platforms.

Note that file permissions are supported on these platforms when you use Java 7 and later, and is supported for all Java versions on Linux, OS X, Windows and FreeBSD for x86 and amd64 architectures.

If you wish to have support for file permissions on other platforms and architectures, please help us port our native integration to these platforms.

Support for terminal integration on certain platforms

Gradle previously supported terminal integration on Solaris and Linux ia-64. This support has been removed. When you use Gradle on these platforms, Gradle will fall back to using plain text output.

Note that terminal integration is supported on Linux, OS X, Windows and FreeBSD for x86 and amd64 architectures.

If you wish to have terminal integration on other platforms and architectures, please help us port our native integration to these platforms.

Build script changes

Gradle now assumes that all Gradle scripts are encoded using UTF-8. Previously, Gradle assumed the system encoding. This change affects all build scripts, settings scripts and init scripts.

It is now an error to include a label on a statement in a Gradle script:

someLabel:
group = 'my.group'

Native binaries model changes

A bunch of changes and renames have been made to the incubating 'native binaries' support. For certain common usages, a backward-compatible api has been maintained.

New Java component model changes

A bunch of changes and renames have been made to the new, incubating 'java component' support.

Support for the deprecated Gradle Open API removed

Properties are no longer dynamically created on assignment

Previously, Gradle would create a property on a domain object when assigning a value to a property that does not exist:

project.myProperty = 'some value'
assert myProperty == 'some value'

This behavior has been deprecated for 2 years of Gradle releases and is now an error. Instead, you should either use the ext namespace or use a local variable:

def myProperty = 'some value'
assert myProperty == 'some value'

// or
ext.myProperty == 'some value'
assert myProperty == 'some value'

+= operator changes that typically affect configuration of eclipse and idea plugin

Due to the Groovy upgrade, assigning configurations to collections via += works differently.

//Gradle 1.12, the assignments have the same effect, both append configuration instance:
list += configurations.compile
list += [configurations.compile]

//Gradle 2.0:
list += configurations.compile //appends the files of the configuration (triggering dependency resolution!)
list += [configurations.compile] //appends the configuration instance

Typically, this change may affect the classpath customization for eclipse and idea. It may cause dependency resolution before any dependencies are added to the configuration. In this case, the user can see an exception like: "You can't change configuration 'someConfig' because it is already resolved!". See below how to resolve this problem:

//Instead:
eclipse.classpath.plusConfigurations += configurations.someConfig
idea.module.scopes.COMPILE.plus += configurations.someConfig

//Prefer below (works with Gradle 1.* and 2.0):
eclipse.classpath.plusConfigurations += [configurations.someConfig]
idea.module.scopes.COMPILE.plus += [configurations.someConfig]

Removed deprecated plugins

Changes to Groovy and Scala plugins

Removed deprecated command line options

Removed deprecated classes

Removed deprecated methods

Removed deprecated properties

Convention properties on Project added by the reporting base plugin:

Convention methods on Project added by the signing plugin:

Changes to file DSL

The Project.file() method no longer accepts arbitrary inputs. Previously, this method would attempt to convert the result of calling toString() on its parameter, if the parameter type was not recognized. This is now an error.

This method is used indirectly in many places in the Gradle DSL.

The CopySpec.into() method also no longer accepts arbitrary inputs. Previously, this method would attempt to conver the result of calling toString() on its parameter, if the parameter type was not recognized. This is now an error.

The Project.tarTree() and zipTree() methods no longer ignores missing files. This is now an error.

Changes to dependency management DSL

The repository DSL has changed:

The Upload task now fails when an artifact does not exist. Previously, this task would ignore the missing artifact.

Tasks cannot be changed after task has started execution

Certain operations on a task are no longer possible once the task has started execution:

This behavior was deprecated and now fails with an exception.

Removed incubating method

Task constructor injection changes

Tasks are now constructed according to JSR-330. This means that a task type must either have a single public zero-args constructor, or annotate one constructor with @Inject.

Previously, Gradle would accept a class with a single constructor with multiple parameters that was not annotated with @Inject. This was deprecated in Gradle 1.2 and is now an error.

Task constructor changes

All core Gradle task types now have a zero args constructor. The following types are affected: