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.
File
objects representing relative pathsHere are the new features introduced in this Gradle release.
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.
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")
}
}
}
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.
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:
NativeToolChain
type now has an eachPlatform(Action<NativePlatformToolChain>)
method, to allow fine-grained customization of a particular tool chain on a per-platform basis.
NativePlatformToolChain.getPlatform()
allows tool chain customization logic access to the target platform.model {
toolChains {
gcc(Gcc) {
eachPlatform { tc ->
if (tc.platform.name == "arm") {
cCompiler.executable = 'gcc-arm'
}
}
}
}
}
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.
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.
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.
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.
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.
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.
TextResource
s 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.
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'
}
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.
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.
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')
}
}
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.
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'
}
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'
}
}
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.
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.
TargetedPlatformToolChain
with GccPlatformToolChain
and VisualCppPlatformToolChain
.PlatformConfigurableToolChain
to GccCompatibleToolChain
.target()
or eachPlatform()
should be used instead.ExecutableBinary
: use NativeExecutableBinary
instead.org.gradle.nativeplatform.sourceset
to org.gradle.language.nativeplatform
org.gradle.language.nativebase
to org.gradle.language.nativeplatform
Native
prefix to existing Platform
, ToolChain
, ToolChainRegistry
and PlatformToolChain
typesNativeComponentSpec.getBinaries()
to return DomainObjectSet<BinarySpec>
NativeComponentSpec.getNativeBinaries()
to return DomainObjectSet<NativeBinarySpec>
org.gradle.language.jvm.ResourceSet
to JvmResourceSet
org.gradle.api.jvm.ClassDirectoryBinarySpec
to org.gradle.jvm.ClassDirectoryBinarySpec
org.gradle.language.jvm.artifact.JavadocArtifact
to org.gradle.language.java.artifact.JavadocArtifact
.Using the internal convention mapping feature for one of the following properties will no longer have an effect:
File
objects representing relative pathsA 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")
.
We would like to thank the following community members for making contributions to this release of Gradle.
maven.repo.local
system propertyAction
overloads project project.exec()
and project.javaexec()
readelf
when parsing output in integration tests.
as decimal separator'sonar-runner'
pluginIdeaModule
model to mark generated source directoriesWe 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.