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!
Test
task support for running tests on Java 5StartParameter.colorOutput
property<dependency>
attributes generated for some project dependenciesorg.gradle.plugins.javascript.rhino.worker
changes and deprecationHere are the new features introduced in this Gradle release that impact all Gradle users.
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:
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.
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.
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.
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!
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.
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.
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`:
classifier
attribute will be included in the <dependency>
entry.<dependency>
entry with the appropriate classifier
attribute will be created for each artifact.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.
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.
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.
There is only one change that directly impacts plugin authors, but it's an important one.
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.
There is just one minor change to the Tooling API, related to composite build support.
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
propertyThe StartParameter.consoleOutput
property has been promoted and is now stable.
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.
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.
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 5Support for using Java 5 with the Test
task type is now deprecated and support will be removed in Gradle 3.0.
StartParameter.colorOutput
propertyThe StartParameter.colorOutput
property has been deprecated and will be removed in Gradle 3.0. You should use the consoleOutput
property instead.
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.
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.
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.
EclipseProjectDependency.getTargetProject()
has been deprecated, use EclipseProjectDependency.getTarget()
instead.IdeaModuleDependency.getDependencyModule()
has been deprecated, use IdeaModuleDependency.getTarget()
instead.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:
Test.getTestSrcDirs()
Test.setTestSrcDirs()
TestNGOptions.getAnnotations()
TestNGOptions.setAnnotationsOnSourceCompatibility()
TestNGOptions.jdkAnnotations()
TestNGOptions.javadocAnnotations()
TestNGOptions.getJDK_ANNOTATIONS()
TestNGOptions.getJAVADOC_ANNOTATIONS()
TestNGOptions.getJavadocAnnotations()
TestNGOptions.isJavadocAnnotations()
TestNGOptions.setJavadocAnnotations()
TestNGOptions.getTestResources()
TestNGOptions.setTestResources()
The setName()
and setProject()
methods in AbstractTask
have been deprecated and will be removed in Gradle 3.0.
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:
getProperty()
, setProperty()
or hasProperty()
methods. These act on all the properties of the object.ext.get()
, ext.set()
or ext.has()
methods. These act only on the 'extra' properties of this object.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.
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:
propertyMissing()
Before Gradle 2.14, the order was:
propertyMissing()
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:
propertyMissing()
must throw a new MissingPropertyException(nameOfProperty, message)
.If propertyMissing()
always returns a value, the extra properties extension (ext
) will stop working as expected.
ComponentModelBasePlugin
can no longer be applied using id component-base
. Its new id is component-model-base
.
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.
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.
<dependency>
attributes generated for some project dependenciesAs 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.
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.
org.gradle.api.artifacts.DependencyArtifact
has setters for all properties to make it clearer that this type is mutable.org.gradle.api.java.archives.ManifestMergeSpec
now has setContentCharset()
and getContentCharset()
methods.org.gradle.plugins.ide.eclipse.model.Facet.FacetType
is no longer decorated with Groovy enum extensions.org.gradle.testing.jacoco.plugins.JacocoTaskExtension.Output
is no longer decorated with Groovy enum extensions.org.gradle.nativeplatform.toolchain.plugins.MicrosoftVisualCppPlugin
has been renamed to org.gradle.nativeplatform.toolchain.plugins.MicrosoftVisualCppCompilerPlugin
.org.gradle.testing.jacoco.plugins.JacocoPluginExtension.applyTo(JavaForkOptions)
signature changed to make it clear this method accepts types that extend Task
and JavaForkOptions
.org.gradle.plugins.javascript.rhino.worker
changes and deprecationThe 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.
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.
org.gradle.util.ConfigureUtil
configure(Closure configureClosure, T delegate, boolean configureableAware)
configure(Closure configureClosure, T delegate, int resolveStrategy)
ConfigureUtil.configure()
can be replaced by Project.configure()
instead.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.
@Validate
rules is immutable, and in the case of ModelMap
and ModelSet
types, readable.components { }
, binaries { }
, testSuites { }
no longer allow elements to be accessed, except as a model reference.For example:
components {
main.targetPlatform "x86"
}
Should be changed to:
components {
main {
targetPlatform "x86"
}
}
We would like to thank the following community members for making contributions to this release of Gradle.
ExtensionContainer
filteringCharset
property to CopySpec
(GRADLE-1267)We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.
Known issues are problems that were discovered post release that are directly related to changes made in this release.