Gradle Release Notes

Version 2.14

The Gradle team is pleased to announce Gradle 2.14.

The team is always working to improve the overall performance of Gradle, and this release does not disappoint. Gradle's configuration time has dropped considerably through the application of some careful optimizations. The Gradle build itself has seen a 50% reduction in configuration time. You'll see the biggest impact on multi-project builds, but everyone will benefit to some degree. This is reason enough to upgrade.

In other news, the Gradle daemon has become self-aware. Not in the AI sense, sadly, but you will find the daemon to be much more robust and resource-efficient now because it monitors its memory usage. It's much less likely that you will need to manually kill daemons. Additionally, an important security vulnerability has been fixed concerning daemon communication and local privilege escalation. For more information read the corresponding section below. We strongly recommend that users upgrade to 2.14.

There are several other quality-of-life improvements for various users, including IntelliJ IDEA support for Play framework projects, and a fix that makes authoring plugins easier. In addition, we mentioned in our 2.13 release notes that composite build support is coming in Buildship 2.0. This amazing new feature will require Gradle 2.14 as a minimum version.

Finally, it's time to start preparing for the departure of an old friend. Gradle 2.14 sees the deprecation of Java 6. It has been with us a long time now, reaching its official End of Life in 2013. You will still be able to use Java 6 with Gradle 2.14 and future versions, but you won't be able to run Gradle 3.0 on it.

Enjoy the new version and let us know what you think!

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release that impact all Gradle users.

Faster Gradle builds

Gradle 2.14 brings significant improvements in configuration time. The Gradle build itself has seen a 50% reduction in its startup time. You should see similar improvements for complex builds or those with lots of subprojects. But even small projects will see a noticeable improvement.

If you're interested in how this was done, here are some of the optimizations that were implemented:

More robust and memory-efficient Daemon

The Gradle daemon now actively monitors garbage collection to identify when it's running out of resources. When this happens, Gradle will restart the daemon as soon as the current build finishes.

The monitoring is enabled by default, but you can disable it by configuring this project property:

org.gradle.daemon.performance.enable-monitoring=false

If you want to disable daemon monitoring for all projects, add this setting to «USER_HOME»/.gradle/gradle.properties. Otherwise, just add it to a gradle.properties file in the root of a project.

In addition to this self-monitoring feature, Gradle now attempts to limit its overall consumption of system resources by shutting down daemons that are no longer in use. Gradle previously stopped daemons after a fixed period of inactivity. In 2.14, idle daemons will expire more quickly when memory pressure is high, thus freeing up system resources faster than before.

Local privilege escalation when using the Daemon

Gradle uses local network connections to communicate with the Gradle Daemon process. In previous versions, it was possible to detect on which local port a daemon process was listening to requests. Since the daemon process did not require authentication, an attacker on the same machine could execute arbitrary scripts using the privileges of the user who originally created the daemon. This vulnerability has been fixed in this release.

Deprecation of Java 6 support

Java 6 reached end of life in February 2013 and support for this version is becoming more difficult as libraries and tools move to Java 7 and later. As a result, Gradle 2.14 will be the last version of Gradle that will run on Java 6, with Gradle 3.0 requiring Java 7 at a minimum.

Please note that while it won't be possible to run Gradle itself on Java 6, your builds will still be able to target Java 6 as a runtime platform with the appropriate sourceCompatibility and targetCompatibility settings.

Play/IDEA Integration

If you're using the Play plugin along with IntelliJ IDEA, you'll be glad to learn that you no longer have to manually configure your projects in the IDE. Instead, you can now apply the IDEA plugin, run the idea task, and load the resulting project file into the IDE. Much easier!

Easier publication and consumption of plugins to and from custom repositories

Gradle 2.1 first introduced the plugins {} block for specifying the plugins that your build uses, but this only worked for plugins that were published to the Gradle plugin portal. With the release of 2.14, you can now specify custom repositories via the new pluginRepositories {} block. This means that you can take advantage of the plugins {} syntax for your organization's private plugins.

To enable this feature, you add the new syntax to the project's settings.gradle file, like so:

pluginRepositories {
    maven {
        url 'https://private.mycompany.com/m2'
    }
    gradlePluginPortal()
    ivy {
        url 'https://repo.partner.com/m2'
    }
}

The plugins {} block looks the same as before, it's just that the plugins can be resolved from different repositories:

plugins {
    id 'java'                               // Resolved from the Gradle Distribution.
    id 'org.public.plugin' version '1.2.3'  // Resolved from the Gradle Plugin Portal.
    id 'com.mycompany.secret' version '1.0' // Resolved from your private Maven repository.
    id 'com.partner.helpful' version '2.0'  // Resolved from your partner's Ivy repository.
}

The repositories are consulted in the order in which they were specifed in the pluginRepositories {} block.

Note The new plugin repository definitions do not work for the apply plugin: <name> syntax. By extension, that also means they won't work with the allprojects {}/subprojects {} feature.

For this feature to work with your own plugins, you will need to publish them alongside a special Plugin Marker Artifact. Don't worry, this step happens automatically when you use either the maven-publish or ivy-publish plugins with the java-gradle-plugin plugin.

To demonstrate how easy it is to publish a plugin with the new marker artifact, here's an example plugin build:

plugins {
    id 'java-gradle-plugin'
    id 'maven-publish'
}

version = 1.0
group = "com.mycompany"

gradlePlugin {
    plugins {
        secret {
            id = 'com.mycompany.secret'
            implementationClass = 'org.mycompany.plugins.TopSecretPlugin'
        }
    }
}

publishing {
    repositories {
        maven {
            url 'https://private.mycompany.com/m2'
        }
    }
}

When you run ./gradlew publish, the sample plugin above, com.mycompany:secretPlugin:1.0, and the plugin marker artifact, com.mycompany.secret:com.mycompany.secret.gradle.plugin:1.0, will both be published to the configured custom Maven repository.

You can learn more about defining custom plugin repositories in the user guide.

Configuration of character encoding when filtering files in a CopySpec

By default, any file filtering performed by a CopySpec uses the default platform character encoding to read and write the filtered files. This can cause problems if the files are encoded with something else, such as UTF-8.

You can now control this behavior by specifying the character encoding to use during the filtering process on a per-CopySpec basis:

task filter(type: Copy) {
    from 'some/place'
    into 'somewhere/else'
    expand(version: project.version)
    filteringCharset = 'UTF-8'
}

See the “Filtering files” section of the “Working with files” chapter in the user guide for more information and examples of how to use this new feature.

We're grateful to Jean-Baptiste Nizet for his contribution of this feature.

Support for inter-project dependency classifiers

When you're publishing artifacts via the maven plugin, Gradle has to map inter-project dependencies to <dependency> declarations in the generated POM file. This normally works fine, but Gradle was previously ignoring the classifier attribute on any project artifacts, which resulted in a single <dependency> entry in the POM for those inter-project dependencies. This meant that the published POM was incorrect and the project could not be properly resolved from a Maven repository.

The mapping of inter-project dependencies into POM dependency declarations has been improved in 2.14. Gradle will now produce correct POM files for the following cases`:

As an example, consider the following Gradle project definitions:

project(':project1') {
    dependencies {
        compile project(':project2')
        testCompile project(path: 'project2', configuration: 'testRuntime')
    }
}

project(':project2') {
    jar {
        classifier = 'defaultJar'
    }

    task testJar(type: Jar, dependsOn: classes) {
        from sourceSets.test.output
        classifier = 'tests'
    }

    artifacts {
        testRuntime  testJar
    }
}

The generated POM file for project1 will now include these dependency entries:

...
<dependencies>
  <dependency>
    <groupId>org.gradle.test</groupId>
    <artifactId>project2</artifactId>
    <version>1.9</version>
    <classifier>defaultJar</classifier>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.gradle.test</groupId>
    <artifactId>project2</artifactId>
    <version>1.9</version>
    <classifier>tests</classifier>
    <scope>test</scope>
  </dependency>
</dependencies>
...

Prior to 2.14, the POM would only contain a single <dependency> entry for 'project2', omitting the classifier attribute altogether.

Many thanks to Raymond Navarette for contributing this feature.

Better control over Ant message logging

In previous versions of Gradle, the mapping of Ant message priorities to Gradle logging levels was fixed and the default LIFECYCLE log level was set to between Ant's "warn" and "info" priorities. This meant that to show output from Ant tasks logged at the common "info" priority, the Gradle logging level had to be set to INFO or DEBUG, potentially exposing unwanted output. Similarly, to suppress unwanted messages from Ant tasks, the Gradle logging level would need to be set to a lower verbosity, potentially suppressing other desirable output.

You can now control the level of Ant logging by changing the message priority that maps to the Gradle LIFECYCLE logging level, like so:

ant {
    lifecycleLogLevel = "INFO"
}

This causes any Ant messages logged at the specified priority - "info" in this case - to be logged at Gradle's LIFECYCLE logging level. Any messages logged at a higher priority than "info" will also be logged at LIFECYCLE level. Messages logged at a lower priority than the specified priority will be logged at INFO level or below.

JAR metadata and manifest content written with UTF-8

Previous versions of Gradle used to encode JAR/WAR/EAR files metadata and Manifests content using the platform default character set instead of UTF-8. Both are bugs and have been fixed in this release.

New for plugin authors

There is only one change that directly impacts plugin authors, but it's an important one.

Better isolation of internal Gradle classes with gradleApi()

In previous versions, Gradle's internal implementation dependencies were visible to plugins at build (i.e. compile and test) but not at runtime. This caused problems when plugins depended on libraries that conflicted with Gradle's internal dependencies, such as Google Guava.

This has been fixed in Gradle 2.14. Only classes that are part of Gradle's public API are now visible to plugins at build time, which more accurately represents the runtime environment for the plugins.

This change fixes both GRADLE-3433 and GRADLE-1715, and requires no changes to your build scripts.

New for tooling API consumers

There is just one minor change to the Tooling API, related to composite build support.

New identifier properties for IDE Tooling API models

New identifier properties on EclipseProject and IdeaModule make it easier to find the IDE model corresponding to a project dependency. Tools should now use EclipseProject.getIdentifier() and EclipseProjectDependency.getTarget() for Eclipse models, and IdeaModule.getIdentifier() and IdeaModuleDependency.getTarget() for IDEA models.

As mentioned in the deprecation notes, these properties supersede EclipseProjectDependency.getTargetProject() and IdeaModuleDependency.getDependencyModule().

Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to our backwards compatibility policy. See the User guide section on the “Feature Lifecycle” for more information.

The following are the features that have been promoted in this Gradle release.

StartParameter.consoleOutput property

The StartParameter.consoleOutput property has been promoted and is now stable.

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.

Setting the log level from build logic

The ability to set the log level from build logic using LoggingManager.setLevel() is now deprecated and scheduled for removal in the next release of Gradle. If you are using this feature to control logging of messages from Ant tasks, please use the AntBuilder.setLifecycleLogLevel() method instead.

Support for running Gradle on Java 6

Running Gradle using Java 6 is now deprecated, and support will be removed in Gradle 3.0.

It will continue to be possible to build JVM based projects for Java 6 using Gradle 3.0, by running Gradle using Java 7 or newer and configuring your build to use Java 6 to compile, test and run your code.

Using the Gradle Tooling API and TestKit on Java 6 is also deprecated, and support will be removed in Gradle 3.0.

Test task support for running tests on Java 5

Support for using Java 5 with the Test task type is now deprecated and support will be removed in Gradle 3.0.

StartParameter.colorOutput property

The StartParameter.colorOutput property has been deprecated and will be removed in Gradle 3.0. You should use the consoleOutput property instead.

Tooling API support for older Gradle versions

Using the Gradle tooling API to run Gradle builds for Gradle versions 1.1 and older is now deprecated. Support for Gradle versions older than 1.2 will be removed in Gradle 3.0.

Using Gradle from a Gradle tooling API version 1.12 and older is now deprecated. Support for Gradle tooling API versions older than 2.0 will be removed in Gradle 3.0.

TestKit support for older Gradle versions

Using the Gradle TestKit to run Gradle build for Gradle versions 1.1 and older is now deprecated. Support for Gradle versions older than 1.2 will be removed in Gradle 3.0.

Build comparison plugin support for older Gradle versions

Using the Gradle build comparison plugin to compare builds for Gradle versions 1.1 and older is now deprecated. Support for Gradle versions older than 1.2 will be removed in Gradle 3.0.

Tooling API model properties

TestNG Javadoc annotations

Support for using TestNG Javadoc annotations is deprecated and will be removed in Gradle 3.0. Support for Javadoc annotations was removed from TestNG 5.12, in early 2010. You will be able to use these old versions of TestNG from Gradle 3.0, however you will need to use JDK annotations.

As a result of this deprecation, the following methods are also deprecated and will be removed in Gradle 3.0:

Deprecated task methods

The setName() and setProject() methods in AbstractTask have been deprecated and will be removed in Gradle 3.0.

Deprecated internal methods

The internal methods has(), get() and set() were unintentionally visible from Groovy for several types such as Project and `Task. This meant that they could be used in Gradle build scripts and plugins implemented in Groovy. These methods have been deprecated and will be removed in Gradle 3.0

These methods can be replaced with calls to either:

Potential breaking changes

Gradle implementation dependencies are not visible to plugins at development time

Implementing a Gradle plugin requires use of the gradleApi() dependency in order to compile against Gradle classes. Previously, this encompassed the entire Gradle runtime including Gradle's third party dependencies (e.g. Guava). If the plugin depended on a library that Gradle also depended on, the behavior was unpredictable as multiple versions of classes could end up on the classpath. This would often manifest as unexpected compile errors or runtime linking errors.

Starting with Gradle 2.14, gradleApi() no longer exposes Gradle's implementation dependencies. As such, the compile and test classes for plugins have changed with this release.

This is expected to be a transparent and compatible change for most plugin builds. While Gradle's implementation dependencies were previously visible at build time, they were not at runtime. As such, it was not possible to successfully ship a plugin that relied on access to Gradle's implementation dependencies.

However, if you were previously using Gradle implementation dependencies in the tests for your plugin, you will need to add these dependencies to your build. For example, if the tests for your plugins use the Guava version shipped by Gradle, you will know need to explicitly declare Guava as a test time dependency. The good news though is that you are now able to choose your own version of Guava (and other Gradle internal dependencies) to use at test time, instead of being bound to the version that Gradle uses.

Changes to dynamic property look-up

Many Gradle objects are ExtensionAware, which means extra properties or methods can be added to them through the extensions container or ext.

For custom task types and custom extension types, you may also use Groovy meta-programming capabilities, such as propertyMissing(). For most use cases, we would recommend that you rely on Gradle's provided extension mechanisms.

In earlier versions, the order in which Gradle searched for dynamic properties and methods did not respect propertyMissing() when implemented by a custom type. Changes have been made to improve the performance of dynamic property look-up and make the order consistent.

The order is:

Before Gradle 2.14, the order was:

Many builds should not be impacted, but custom tasks or extensions that use both propertyMissing() and ext need to be careful to implement propertyMissing() with the appropriate semantics:

If propertyMissing() always returns a value, the extra properties extension (ext) will stop working as expected.

Change in plugin id

ComponentModelBasePlugin can no longer be applied using id component-base. Its new id is component-model-base.

Tests now respect java.util.logging.config.file by default

Previous versions of Gradle ignored the java.util.logging.config.file system property when running tests. Now, the system property will be honored when tests are running. This can break your tests if you are expecting the default ConsoleHandler to be used during tests, and checking expectations based on that output. If you tests begin failing with this release of Gradle, you can disable reading the logging conifguration file with a system propoerty.

test {
    systemProperty 'org.gradle.readLoggingConfigFile' 'false'
}

Support for this system property will be dropped in Gradle 3.0. Please be sure to correct the expectations in your tests if you are using a logging configuration file.

JAR metadata and Manifest content encoding

Previous versions of Gradle used to encode JAR/WAR/EAR files metadata and Manifests content using the platform default character set instead of UTF-8. Both are bugs and have been fixed in this release, see the related fixed issues above.

Following this, merged manifests are now read using UTF-8 instead of the platform default charset.

If necessary, convenience properties have been added to Jar, War, Ear tasks and ManifestMergeSpec to control which character set to use when merging manifests.

In order to fall back to the old behavior you can do the following:

jar {
    // JAR metadata
    metadataCharset = Charset.defaultCharset().name()
    // Manifest content
    manifestContentCharset = Charset.defaultCharset().name()
    manifest {
        // Merged manifest content
        from(file('path/to/some/manifest/to/merge')) {
            contentCharset = Charset.defaultCharset().name()
        }
    }
}

To support this change, a contentCharset property has been added to the ManifestMergeSpec type.

Additional POM <dependency> attributes generated for some project dependencies

As described above, POM files generated by the maven plugin now include classifiers and all artifacts for project dependencies. This improvement may break existing Gradle builds, particularly those that include a specific workaround for the previous behavior. These workarounds should no longer be required, and may need to be removed to ensure that Gradle 2.14 will create correct <dependency> attributes for project dependencies.

A number of plugins were converted from Groovy to Java

The following plugins were fully converted to Java: jacoco, scala, osgi, javascript, distribution and announce.

Some other plugins were partially converted to Java, keeping tasks types as Groovy classes: init, checkstyle, codenarc, findbugs, pmd, jdepend, java, war, ear, application, signing, comparison, idea and eclipse. For the latter two, plugin types have also been kept in Groovy.

Existing builds and plugins should continue to work.

API method changes

org.gradle.plugins.javascript.rhino.worker changes and deprecation

The method for creating a handle to a Rhino-backed worker has changed in RhinoWorkerHandleFactory. All classes in this package have been deprecated and will be moved to an internal package.

Changes to internal APIs

Please note that internal APIs may change between releases and will not necessarily be mentioned in release notes. The list of classes available in our Javadoc and Groovydocs represent the public API.

Source and target compatibility options are always passed to the Java compiler

The target-/sourceCompatibility options for the Java Plugin default to the version of Java used to start Gradle.

Before this version, if the target-/sourceCompatibility options were the same as the version of Java used to start Gradle, no -source/-target options have been passed to the compiler, even if running in forked mode.

Beginning from this version the -source/-target options are always passed to the compiler.

Experimental software model changes

For example:

components {
    main.targetPlatform "x86"
}

Should be changed to:

components {
    main {
        targetPlatform "x86"
    }
}

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.