Here are the new features introduced in Gradle 1.2.
The dependency report (obtained by running “gradle dependencies
”) has been improved to provide better insight into the dependency resolution process. The report now specifies the requested version of a dependency and the selected version. The requested version may be different to the selected for the following reasons:
1.3.+
”)In the case of a conflict, the output provides all the information you need to infer which dependency depended on the version that was eventually selected. The improved output gives much better insight into how version conflicts that were encountered were resolved and why.
In the case of a dynamic dependency version, both the original dynamic version and selected real version are shown.
The new dependency report is also much faster to render. Our tests have shown that for large to very large dependency graphs the time taken to display the report has been reduced by up to 50%. Further improvements are planned for the dependency report in future versions of Gradle.
Given the following build script:
apply plugin: 'java'
repositories {
maven { url "http://repo.gradle.org/gradle/repo" }
}
dependencies {
compile 'commons-lang:commons-lang:2.+'
compile 'org.gradle:gradle-base-services:1.1' // depends on org.slf4j:slf4j-api:1.6.6
compile 'org.slf4j:slf4j-api:1.6.5'
}
The new report will look like:
> gradle dependencies :dependencies ------------------------------------------------------------ Root project ------------------------------------------------------------ compile - Classpath for compiling the main sources. +--- commons-lang:commons-lang:2.+ -> 2.6 +--- org.gradle:gradle-base-services:1.1 | \--- org.slf4j:slf4j-api:1.6.6 \--- org.slf4j:slf4j-api:1.6.5 -> 1.6.6 (*) (*) - dependencies omitted (listed previously)
(note: output for other configurations has been omitted for clarity)
The version that was selected for the dynamic dependency is shown (i.e. “commons-lang:commons-lang:2.+ -> 2.6
”) and the fact that version “1.6.5
” of “org.slf4j:slf4j-api
” was requested but version “1.6.6
” was selected is also shown.
We've continued to improve our dependency resolution engine, so that it now requires much less heap space. A moderately sized multi-project build can expect to see a 20-25% reduction in heap usage thanks to these improvements.
When running the build with --continue
or the new --parallel
option it is possible to have multiple failures in your build. Previously, these failures were only reported at the time they occurred. Now, additionally a complete list of build failures is shown on build completion.
The new output clearly indicates the cause and possible analysis of each failure, making it easier to track down the underlying issue. Detailing all failures makes the --continue
command line option much more useful: it is now possible to use this option to discover as many failures as possible with a single build execution.
Thanks to a contribution from Justin Ryan, the FindBugs plugin now supports more configuration options.
Important: In Gradle 1.2, there is an identified issue that requires any FindBugs specific configuration to be performed on the task; configuration via the DSL extension is ineffectual. Please click the “More” button below for instructions on how to workaround this issue.
Instead of configuring FindBugs
properties for all tasks globally via the DSL extension:
findbugs {
excludeFilter = file("$rootProject.projectDir/config/findbugs/excludeFilter.xml")
}
You need to configure the task(s) directly, which can be done via:
tasks.withType(FindBugs) {
excludeFilter = file("$rootProject.projectDir/config/findbugs/excludeFilter.xml")
}
This applies to all FindBugs specific task properties.
This issue will be resolved in Gradle 1.3, allowing you to globally configure all FindBugs
tasks via the DSL extension.
Gradle, the Gradle Wrapper and the Gradle Tooling API now provide version information in the User-Agent
header whenever HTTP resources are accessed. Especially for larger organizations, this can be very helpful to gather information about which versions of Gradle are used in which environment.
The User-Agent
header now includes information about
An example for a Gradle generated user-agent string: "Gradle/1.2 (Mac OS X;10.8;amd64) (Oracle Corporation;1.7.0_04-ea;23.0-b12)"
Our documentation has received a facelift to match our new style. Check out the new look DSL Reference and User Guide.
The DSL Reference also now indicates which features are deprecated or incubating. See TestLoggingContainer for and example of how an incubating feature is displayed, and Directory for an example of a deprecated feature.
Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to our backwards compatibility policy.
--continue
)Often a high-level task is dependent on multiple smaller tasks. By default, Gradle will stop executing any task and fail the build as soon as one of these sub-tasks fails. This means that the build will finish sooner, but it does not reveal failures in other, independent sub-tasks. There are many times when you would like to find out as many failures as possible in a single build execution. For example, when you kick off a build before heading out to lunch, or running a nightly CI job. The --continue
command-line option allows you to do just that.
With the addition of nicer reporting of multiple build failures, we now consider --continue
a production quality feature of Gradle. Please see the User Guide section for more details.
The list of issues fixed between 1.1 and 1.2 can be found here.
We will typically introduce new features as incubating at first, giving you a chance to test them out. Typically the implementation quality of the new features is already good but the API might still change with the next release based on the feedback we receive. For some very challenging engineering problems like the Gradle Daemon or parallel builds, it is impossible to get the implementation quality right from the beginning. So we need you here also as beta testers. We will iterate on the new feature based on your feedback, eventually releasing it as stable and production-ready. Those of you who use new features before that point gain the competitive advantage of early access to new functionality in exchange for helping refine it over time. To learn more, read our forum posting on our release approach.
Gradle 1.2 delivers the first iteration of our support for comparing the outcomes (e.g. the produced binary archives) of two builds. There are several reasons why you may want to compare the outcomes of two builds. You may want to compare:
The build comparison support manages the execution of the “source” build and the “target” build, the association of outcomes between the two, the comparison of the outcomes and generation of a report that identifies any encountered differences. You can then use this report to go ahead with the Gradle upgrade, build system migration or build configuration change with confidence that the outcomes are identical, or that the differences are acceptable.
For Gradle 1.2, we have focused on supporting the case of comparing the current build with a newer Gradle version and zip archive outcomes (e.g. zip, jar, war, ear etc.). This feature will continue to evolve to encompass comparing more kinds of outcomes and smart integration with other build systems (such as Apache Maven) for convenient comparisons.
See the new User Guide chapter for more detail on this new capability.
You simply add a plugin and configure the comparison task.
apply plugin: 'compare-gradle-builds'
compareGradleBuilds {
targetBuild.gradleVersion "1.3"
}
(note: Gradle 1.3 is unreleased at this time, so the above will not work. You can use 1.2 as the value in the meantime to play with this feature though)
Then simply…
> gradle compareGradleBuilds
If there are any differences found, a link to the HTML report identifying the differences will be given in the output.
We are excited that Gradle 1.2 introduces support for building projects in parallel. By specifying the --parallel
or --parallel-threads
command-line options, Gradle will execute multiple projects in parallel build threads, after first configuring all projects sequentially. By building separate projects in parallel, Gradle will better utilize the build machine's hardware, resulting in faster build times. We are seeing significant performance benefits with this approach.
This feature is incubating and has known issues and limitations; it is not yet at production quality. Over the coming releases, it will be improved and stabilized. To find out more about our plans for parallel execution, have a read of the parallel-project-execution specification.
To guarantee successful parallel execution of projects, your multi-project build must be decoupled. At this time there are no checks implemented to ensure that projects are decoupled, and unexpected behaviour may result from executing a build with coupled projects using the new parallel executor.
One known issue is that the Gradle compiler daemon is currently not thread-safe. So if multiple projects attempt to compile java code simultaneously with fork=true
, exceptions will result. Workaround: don't use options.fork=true
to compile when running with --parallel
.
We are exposing the new API that our improved dependency reports are using. It provides a powerful toolkit for developing your own custom dependency reports. It also allows to develop smart build logic that can make decisions based on the content of the dependency graph.
The best way to start with the new API is to take a look at the Javadocs for ResolvedConfiguration.getResolutionResult()
.
We've taken some steps towards allowing JSR-330 style dependency injection for plugins and tasks. At this stage, the changes are mostly internal. To find out why we want to use dependency injection, and our plans for this, have a read of the dependency-injection-for-plugins specification.
At this stage, only internal Gradle services are available for injection. Over time we will add public services that can be injected into plugin and task implementations.
If you make use of the deprecated features below you will get a warning from now on. But you can rest assured that those features will be supported at least until the release of Gradle 2.0, our next major release. To learn more read our forum posting on our release and backwards compatibility approach.
useMavenMetadata
property for Maven repositoriesThe useMavenMetadata
property has been deprecated for resolvers returned by repositories.mavenRepo()
. This property controls whether Gradle should search for a maven-metadata.xml
file when attempting to determine the versions that are available for a particular module. The default value is true
, which means Gradle will look for a maven-metadata.xml
file and then fall back to a directory listing if not present. When set to false
, Gradle will use a directory listing only. It is part of our former internal usage of Ivy for dependency resolution.
Thanks to the various improvements we've made to make dependency management more efficient, there is no longer a performance penalty for searching for the maven-metadata.xml
file. This means this property is no longer useful and will be removed in Gradle 2.0.
To avoid ambiguity, the Java and C++ Compile
task classes have been renamed. The Java org.gradle.api.tasks.compile.Compile
task class has been renamed to org.gradle.api.tasks.compile.JavaCompile
, and the incubating C++ org.gradle.plugins.binaries.tasks.Compile
task class has been renamed to org.gradle.plugins.cpp.CppCompile
.
For backwards compatibility, the old classes are still available, but are now deprecated. The old Java Compile
class will be removed in Gradle 2.0. The old incubating C++ Compile
class will be removed in Gradle 1.3.
As a first step towards handling JSR-330 style dependency injection for plugin and task instances, we have made some changes to how constructors for these types are handled by Gradle. These changes are fully backwards compatible, but some combinations of constructors are now deprecated.
If your plugin or task implementation class has exactly one default constructor, nothing has changed. This should be the case for the majority of implementations.
If your implementation class has multiple constructors, you will need to add an @javax.inject.Inject
annotation to the default constructor. The implementation will continue to work without this, but you will receive a deprecation warning. In Gradle 2.0, a plugin or task implementation with multiple constructors will be required to annotate exactly one constructor with an @Inject
annotation.
See constructor handling above. The changes should be backwards compatible. Please let us know if you come across a situation where a plugin or task implementation that worked with previous versions of Gradle does not work with Gradle 1.2.
Gradle uses the ASM bytecode manipulation library internally. The version of ASM used has been upgraded from 3.3.1
to 4.0
in the Gradle 1.2 release.
When building and testing custom plugins and build logic (or anything with the Gradle libraries and dependencies on the classpath), you may encounter issues if there is also an earlier version of ASM than 4.0
on the classpath. This error will manifest as an exception with a message such as:
Caused by: java.lang.IncompatibleClassChangeError: Found interface org.objectweb.asm.MethodVisitor, but class was expected
There have been some reports of this issue occurring in the Groovy Eclipse development environment.
If you experience this issue, please let us know via the Gradle Forums.