Continuing on with the performance improvements delivered in recent Gradle versions, 1.5 brings wide reaching optimizations to dependency resolution as well as important improvements to two recent features; configure-on-demand and parallel execution. Gradle continues to embrace the challenges of large scale build automation. Along with the performance improvements comes the usual mix of new features, bug fixes, usability improvements and refinements.
The dependency resolve rule feature introduced in 1.4 gains new capabilities in 1.5. Trouble dependencies can now be completely substituted at resolution time which enables solving some very tricky issues with complex dependency graphs. On the publication side, the new (incubating) Maven and Ivy publishing plugins gain new capabilities making them able to solve more publishing use cases with elegance.
A very exciting trend is the increase in code and documentation contributions from the community, both large and small. Some very useful new features such as the "build dashboard" and "distributions" plugins added in this release, to name a few, came by way of contribution. If you'd like to get involved and contribute to Gradle, a great place to start is gradle.org/contribute.
The Gradle team is also excited to announce the first ever “Gradle Summit” (Sponsored by Gradleware), held June 13th - 14th in Santa Clara, California. The summit will be two fully packed days of technical sessions given by Gradle core developers ranging from introductory to deep dive as well as informational sessions by several large organizations on how they get the most out of Gradle. In between sessions there'll be plenty of opportunity for talking to other Gradle users and the Gradle development team. This is an event not to miss. Registration is now open.
Read on for more details on why you should upgrade to Gradle 1.5. As always, please share your feedback and experiences with Gradle 1.5 via the Gradle Forums.
Here are the new features introduced in this Gradle release.
This release brings performance improvements for JUnit and TestNG test execution as well as dependency resolution improvements for all builds that use dependency resolution.
Test execution has been further optimized in this release, continuing on the work in Gradle 1.4. The test report is now generated more efficiently, so that it take less time and heap space to generate the HTML report. In addition, for those projects that use the TestNG framework, the test JVM now starts more quickly, meaning that test execution starts earlier than it did in previous Gradle releases.
Gradle's dependency cache is multi process safe, which requires the use of locking mechanisms. Improvements to the way the locks are utilised in this release have increased the dependency resolution speed by up to 30% for builds that use local repositories or maven local. Builds that don't use local repositories should also exhibit slightly faster dependency resolution. Every build that resolves dependencies benefits from this improvement.
Gradle 1.4 introduced the ability to dynamically change the version of a dependency to be resolved via dependency resolve rules. It is now possible to change the group, name and/or version of a requested dependency, allowing a dependency to be substituted with a completely different dependency during resolution.
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.name == 'groovy-all') {
details.useTarget group: details.requested.group, name: 'groovy', version: details.requested.version
}
}
}
Dependency resolve rules can now be used to solve some interesting dependency resolution problems:
log4j
with a compatible version of log4j-over-slf4j
.slf4j
bindings with slf4j-simple
.groovy-all
with groovy
.ant:ant:*
with org.apache.ant:ant:1.7.0
and let conflict resolution take care of the rest.'javax.servlet:servlet-api:2.4'
at compile time and the jetty implementation at test runtime.For more information, including more code samples, please refer to the user guide.
Gradle 1.5 ships with a new sonar-runner
plugin that is set to replace the existing Sonar plugin. As its name indicates, the new plugin is based on the Sonar Runner, the new and official way to integrate with Sonar. Unlike the old Sonar plugin, the new Sonar Runner plugin is compatible with the latest Sonar versions (3.4 and above). To learn more, check out the Sonar Runner Plugin chapter in the Gradle user guide, and the sonarRunner
samples in the full Gradle distribution.
When the IDEA plugin encounters a Scala project, it will now add additional configuration to make the project compile in IntelliJ IDEA out of the box. In particular, the plugin adds a Scala facet and a Scala compiler library that matches the Scala version used on the project's class path.
Gradle 1.4 introduced a new operational mode called “configure-on-demand” designed to improve Gradle performance on large projects. This release brings the following improvements to this new feature:
Enabling this new mode is now more convenient. It can be enabled at invocation time via the new --configure-on-demand
flag, or via the org.gradle.configureondemand
project property. The project property can be set permanently for a project, or permanently for a user just like other build settings.
For example, by adding a gradle.properties
file to root of the project with the following content Gradle will always use configure-on-demand mode for the project.
#gradle.properties file
org.gradle.configureondemand=true
For more information on configure-on-demand please consult the user guide.
Gradle 1.2 introduced a parallel execution mode for multi-project builds. This release brings significantly improved utilisation of the parallel workers.
Previously, workers where statically assigned to projects and often waited for the upstream dependencies to be built. This caused workers to stay idle when there was work they could be doing. The distribution of work is now more dynamic which has resulted in highly parallelizable builds building up to 30% faster.
It is also now possible to enable parallel building via a build setting. For example, by adding a gradle.properties
file to root of the project with the following content Gradle will always build the project in parallel.
//gradle.properties file
org.gradle.parallel=true
Thanks to a contribution from Sébastien Cogneau, a new distribution
plugin has been added. This plugin adds general-purpose for support bundling and installing distributions.
This plugin adds a main
distribution, and you can add additional distributions. For each distribution, tasks are added to create a ZIP or TAR file for the distribution and to install the distribution.
You can define multiple distributions:
distributions {
enterprise
community
}
To build the additional distributions you can run the generated Zip
tasks enterpriseDistZip
and communityDistZip
. For more information, please consult the user guide.
The Java library distribution plugin now extends the newly introduced distribution plugin. Thanks to this, you can now create tar files and install Java library distributions.
For more information, please consult the user guide.
Project dependencies at configuration time are now fully supported. Prior to this change, any resolution of a project dependency at configuration time may have led to confusing behavior as the target project may not have been configured yet. Now the resolution of the project dependency implies configuration of the target project. This means that the order in which projects are configured may now be different (i.e. it will be correct). This change should not cause any trouble in existing builds and it fixes up the confusing behavior with project dependencies.
The 'maven-publish
' and 'ivy-publish
' plugins gain new features and capabilities in this Gradle release.
Gradle 1.5 introduces the concept of a “Software Component”, which defines something that can be produced by a Gradle project such as a Java library or a web application. Both the 'ivy-publish
' and 'maven-publish
' plugins are component-aware, simplifying the process of publishing a module. The component defines the set of artifacts and dependencies for publishing.
Presently, the set of components available for publishing is limited to 'java
' and 'web
', added by the 'java
' and 'war
' plugins respectively. In the future it will be possible to create new components and new component types.
Publishing the 'web
' component will result in the war file being published with no runtime dependencies (dependencies are bundled in the war):
apply plugin: 'war'
apply plugin: 'maven-publish'
group = 'group'
version = '1.0'
// … declare dependencies and other config on how to build
publishing {
repositories {
maven { url 'http://mycompany.org/mavenRepo' }
ivy { url 'http://mycompany.org/ivyRepo' }
}
publications {
mavenWeb(MavenPublication) {
from components.web
}
ivyWeb(IvyPublication) {
from components.java // Include the standard java artifacts
}
}
}
This release introduces the ability to customize the set of artifacts to publish to a Maven repository or an Ivy repository. This gives complete control over which artifacts are published, and the classifier/extension used to publish them.
Due to differences in the capabilities of Ivy vs Maven repositories, the DSL is slightly different for each repository format.
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'ivy-publish'
group = 'group'
version = '1.0'
// … declare dependencies and other config on how to build
task sourceJar(type: Jar) {
from sourceSets.main.allJava
classifier "source"
}
publishing {
repositories {
maven { url 'http://mycompany.org/mavenRepo' }
ivy { url 'http://mycompany.org/ivyRepo' }
}
publications {
mavenCustom(MavenPublication) {
from components.java // Include the standard java artifacts
artifact sourceJar {
classifier "source"
}
artifact("project-docs.htm") {
classifier "docs"
extension "html"
builtBy myDocsTask
}
}
ivyCustom(IvyPublication) {
from components.java // Include the standard java artifacts
artifact(sourceJar) {
type "source"
conf "runtime"
classifier "source"
}
artifact("project-docs.htm") {
classifier "docs"
extension "html"
builtBy myDocsTask
}
}
}
}
Be sure to check out the DSL reference for MavenPublication and IvyPublication for complete details on how the set of artifacts can be customized.
For more information about using the new 'maven-publish
' and 'ivy-publish
' plugins in general, please consult the user guide (maven) (ivy).
POM file generation has been moved into a separate task, so that it is now possible to generate the POM file without actually publishing your project. All details of the publishing model are still considered in POM generation, including components
, custom artifacts
, and any modifications made via pom.withXml
.
The task for generating the POM file is of type GenerateMavenPom
, and is given a name based on the name of the publication: generatePomFileFor<publication-name>Publication
. So in the above example where the publication is named 'mavenCustom
', the task will be named generatePomFileForMavenCustomPublication
.
Where supported by the underlying metadata format, Gradle will now handle any valid Unicode character in module group, name and version as well as artifact name, extension and classifier.
The only values that are explicitly prohibited are '\', '/' and any ISO control character. Supplied values are validated early in publication.
A couple of caveats to the Unicode support:
groupId
' and 'artifactId
' to a limited character set ([A-Za-z0-9_\\-.]+
) and Gradle enforces this restriction.:
' character cannot be used as an identifier when publishing to a filesystem-backed repository on Windows.It is now possible to enable the equivalent of Ivy's dynamic resolve mode when resolving dependencies. This is only supported for Ivy repositories.
See the user guide for examples and further details.
Thanks to a contribution from Marcin Erdmann, a new build-dashboard
plugin has been added. This plugin adds a task to projects to generate a build dashboard HTML report which contains references to all reports that were generated during the build. In the following example, the build-dashboard
plugin is added to a project which has also the groovy
and the codenarc
plugin applied:
apply plugin: 'groovy'
apply plugin: 'build-dashboard'
apply plugin: 'codenarc'
By running the buildDashboard
task after other tasks that generate reports (e.g. by running gradle check buildDashboard
), the generated build dashboard contains links to the codenarc
reports. This version of the build dashboard does not include links to test reports. This plugin is in the early stages of development and will be significantly improved in future Gradle releases.
More information on the build-dashboard
plugin can be found in the user guide.
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 2.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.
ArtifactRepositoryContainer.getResolvers()
This method exposes internal implementation details that will be subject to change in the future. Its use should be avoided.
Breaking changes have been made to the incubating 'maven-publish
' plugin, which provides an alternative means to publish to Maven repositories.
publications
container; no publication is added implicitly by the maven-publish
plugin.
MavenPublication
is configured then nothing will be published.MavenPublication
does not include any artifacts or dependencies by default; these must be added directly or via a SoftwareComponent
.
groupId
, artifactId
and version
in the published pom cannot be changed via MavenPom.withXml()
: it was previously possible change these values, but any interproject dependency would not pick up these changes.
groupId
, artifactId
, version
, ext
, classifier
) have new character restrictions: these identifiers may not contain '/
', '\
' or any ISO Control Characters. Using these values generally made it impossible to resolve these modules, so this is now prevented at the time of publication.groupId
and artifactId
are further restricted to "[A-Za-z0-9_\-.]+
": this is a Maven restriction, so it is enforced at the time of publication.GenerateMavenPom
task for a publication is not created until the publishing extension is first accessed. Any attempt to configure a GenerateMavenPom
task should be enclosed within a publishing
block.publishing
block.Be sure to check out the Maven Publishing User Guide Chapter and the MavenPublication DSL reference for complete description and examples of the new Maven Publishing support.
Breaking changes have been made to the incubating 'ivy-publish
' plugin, which provides an alternative means to publish to Ivy repositories.
IvyPublication
must be explicitly added to the publications
container; no publication is added implicitly by the ivy-publish
plugin.
IvyPublication
is configured then nothing will be published.IvyPublication
does not include any artifacts or dependencies by default; these must be added directly or via a SoftwareComponent
.
ivy.xml
file will be published with no artifacts or dependencies declared.organisation
, name
and revision
cannot be changed via IvyDescriptor.withXml()
: it was previously possible to do this, although it did not change the actual identity of the published module.
organisation
, module
, revision
) and artifacts (name
, ext
, type
, classifier
) have new character restrictions: these identifiers may not contain '/
', '\
' or any ISO Control Characters. Using these values generally made it impossible to resolve these modules, so this is now prevented at the time of publication.GenerateIvyDescriptor.xmlAction
property. The ivy.descriptor.withXml()
method provides a way to customise the generated module descriptor.GenerateIvyDescriptor
task for a publication is not created until the publishing extension is first accessed. Any attempt to configure a GenerateIvyDescriptor
should be enclosed within a publishing
block.publishing
block.Be sure to check out the Ivy Publishing User Guide Chapter and the IvyPublication DSL reference for complete description and examples of the new Ivy Publishing support.
Improving the usability of project dependencies (see the section above) might change the order in which projects are configured. This is not expected to cause problems in existing builds, but is mentioned for completeness.
Parallel builds are now much faster due to better utilisation of parallel workers. However, this means that tasks may be executed in different order in parallel builds. This will not cause problems in a correctly decoupled build but may bring problems to light in builds that are not properly decoupled.
The distribution
extension that is added by the java-library-distribution
plugin was removed. The main
distribution is now accessible using the distributions
extension:
distributions {
main {
...
}
}
We would like to thank the following community members for making excellent contributions to this release of Gradle.
ivy.xml
where dependency configuration contained wildcard values (GRADLE-2352)targetJdk
for PMD code analysis (GRADLE-2106)build-dashboard
pluginmaxHeapSize
property to FindBugs
task to allow setting the max heap size for spawned FindBugs java processcontentsCompression
property to the Zip
task type to specify the compression level of the archiveSourceSetOutput
documentationWe 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.