This is a significant release that includes exciting new features and some very important stabilization and optimization, particularly in the area of dependency management.
Our commitment to the Scala language as a first class citizen in the Gradle ecosystem is evident in this release. Through our hardwork, in cooperation with the folks from Typesafe, Gradle now ships with one of the most frequently requested improvements from Scala developers: decreased compile times through incremental compilation. The ability to fork compilation has also been added along with improvements to Eclipse integration for Gradle Scala projects.
As software becomes more and more modular and componentized, development teams are requiring more sophistication and more flexibility in how their built items are published for downstream consumption. This release includes the first step towards a richer and more powerful publication approach within Gradle, that provides the ability to completely customize the Ivy module descriptor created when publishing in the Ivy format.
Dependency management is a critical Gradle function. Many important fixes/optimizations have been made in this release that improve the general dependency management experience in many areas. Along with these improvements, there is an extremely useful new dependency report that can be used to extract precise information from the resolved dependency graph, with regard to a particular dependency. This report is enabled by the powerful new Resolution Result API introduced in Gradle 1.2, that has been further refined in this release. You can expect to see further improvements and innovation in this area in future Gradle versions.
As always, you can share your feedback and experiences with Gradle 1.3 via the Gradle Forums. Please read on for detailed information about this release.
Here are the new features introduced in this release.
The new dependencyInsight
report complements the dependencies
report (that was improved in Gradle 1.2). Where the dependencies
report provides information on the whole dependency graph, the dependencyInsight
report focusses on providing information on one (or more) dependencies within the graph.
The report can be used to answer (very common) questions such as:
The selected version of a dependency can be different to the requested (i.e. user declared) version due to dependency conflict resolution or by explicit dependency force rules. Similar to the standard gradle depenency report, the dependencyInsight
report shows both versions. It also shows a requested dynamic version (e.g. “junit:junit:4.+
”) together with the actually selected version (e.g. “junit:junit:4.10
”). Please keep in mind that Maven snapshot dependencies are not treated as dynamic versions but as changing modules, similar to what Maven does (for the difference see the userguide). Maven snapshots might be treated as dynamic versions in a future version of Gradle which would provide nice insight into pom snapshot resolution.
The dependencyInsight
report task is invaluable when investigating how and why a dependency is resolved, and it is available in all projects out of the box.
Given the following build script:
apply plugin: 'java'
repositories {
maven { url "http://repo.gradle.org/gradle/repo" }
}
dependencies {
compile 'org.gradle:gradle-tooling-api:1.2'
compile 'org.slf4j:slf4j-api:1.6.5'
}
Let's find out about the org.gradle:gradle-messaging
dependency:
> gradle dependencyInsight --dependency org.gradle:gradle-messaging :dependencyInsight org.gradle:gradle-messaging:1.2 +--- org.gradle:gradle-tooling-api:1.2 | \--- compile \--- org.gradle:gradle-core:1.2 \--- org.gradle:gradle-tooling-api:1.2 (*) (*) - dependencies omitted (listed previously)
Using this report, it is easy to see that the gradle-messaging
dependency is being included transitively through gradle-tooling-api
and gradle-core
(which itself is a dependency of gradle-tooling-api
).
Whereas the dependencies
report shows the path from the top level dependencies down through the transitive dependencies, the dependencyInsight
report shows the path from a particular dependency to the dependencies that pulled it in. That is, it is an inverted view of the dependencies
report.
The dependencyInsight
report is also useful for understanding the difference between requested and selected versions.
> gradle dependencyInsight --dependency slf4j --configuration runtime :dependencyInsight org.slf4j:slf4j-api:1.6.6 (conflict resolution) +--- org.gradle:gradle-tooling-api:1.2 | \--- runtime +--- org.gradle:gradle-messaging:1.2 | +--- org.gradle:gradle-tooling-api:1.2 (*) | \--- org.gradle:gradle-core:1.2 | \--- org.gradle:gradle-tooling-api:1.2 (*) +--- org.gradle:gradle-base-services:1.2 | +--- org.gradle:gradle-tooling-api:1.2 (*) | +--- org.gradle:gradle-messaging:1.2 (*) | \--- org.gradle:gradle-core:1.2 (*) \--- org.gradle:gradle-core:1.2 (*) org.slf4j:slf4j-api:1.6.5 -> 1.6.6 \--- runtime (*) - dependencies omitted (listed previously)
Here we see that while slf4j-api:1.6.5
was requested, slf4j-api:1.6.6
was selected due to the conflict resolution. We can also see which dependency pulled in the slf4j.
In this case, we were interested in the runtime
dependency configuration. The default configuration the report uses is compile
.
For more information, see the DependencyInsightReportTask documentation.
Due to the sophistication of the language and type system, Scala programs can take a long time to compile. Gradle 1.3 addresses this problem by integrating with Zinc, a standalone version of sbt's incremental Scala compiler. By compiling only classes whose source code has changed since the previous compilation, and classes affected by these changes, Zinc can significantly reduce Scala compilation time. It is particularly effective when frequently compiling small code increments, as is often done at development time.
To switch the ScalaCompile
task from the default Ant based compiler to the new Zinc based compiler, use scalaCompileOptions.useAnt = false
. Except where noted in the API documentation, the Zinc based compiler supports exactly the same configuration options as the Ant based compiler.
Just like the Ant based compiler, the Zinc based compiler supports joint compilation of Java and Scala code. By default, all Java and Scala code under src/main/scala
will participate in joint compilation. With the Zinc based compiler, even Java code will be compiled incrementally.
To learn more about incremental Scala compilation, see the Scala plugin chapter in the Gradle User Guide.
Scala compilation can now be performed outside the Gradle JVM in a dedicated compiler process, which can help to deal with memory issues.
External compilation is supported both for the existing Ant-based and the new Zinc-based Scala compiler. The API is very similar to that for Java and Groovy: ScalaCompile.fork = true
activates external compilation, and ScalaCompile.forkOptions
allows to adjust memory settings.
The Eclipse Plugin now automatically excludes dependencies already provided by the 'Scala Library' class path container. This improvement is essential for Scala IDE to work correctly. It also takes effect when using the Eclipse Gradle Integration.
With this release of Gradle, we have continued to improve our dependency management implementation. The focus for these improvements in Gradle 1.3 is on stability and this release includes a number of important fixes.
This release fixes a number of issues that resulted in corruption of the artifact cache. In particular, Gradle will be much more stable in the case where you have many concurrent builds running on a machine, such as a CI build server, and these builds have dependencies that change frequently, such as Maven snapshots, or are using a very short cache expiry time.
Gradle caches the fact that a given module is missing from a given repository. It uses this information to avoid unnecessary network requests when you are using multiple repositories, and when resolving dynamic versions. Previous versions of Gradle were overly keen in using this information, leading to problems where a misconfiguration would cause Gradle to decide that a certain module is missing and will be missing forever. In this release, Gradle uses a more sensible strategy to decide when to verify that something that it considers to be missing is, in fact, missing.
Previous Gradle releases had a number of issues resolving dynamic versions such as 'latest.integration' and we recently introduced some regressions in this area as we've attempted to fix these issues. We've reworked the implementation to simplify it internally and added many more integration tests, to avoid further regressions in the future.
This release includes a number of other useful fixes:
Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to the backwards compatibility policy.
Gradle 1.1 introduced much improved test logging output. The APIs that provided the ability to configure this logging were introduced in the incubating state. In this Gradle release, these APIs are being promoted and are no longer subject to change without notice.
For more information on the test logging functionality, see this forum post that introduced the feature.
The list of issues fixed between 1.2 and 1.3 can be found here.
New features as typically introduced as “incubating”. The key characteristic of an incubating feature is that it may change in an incompatible way in a future Gradle release. At some time in the future, after incorporating invaluable real-world feedback from Gradle users, the feature will be deemed stable and “promoted”. At this point it is no longer subject to incompatible change. That is, the feature is now subject to the backwards compatibility policy.
Typically, the implementation quality of incubating features is sound. For some very challenging engineering problems, such as the Gradle Daemon or parallel task execution, it is impossible to get the implementation quality right from the beginning as the feature needs real world exposure. The feedback from the incubation phase can be used to iteratively improve the stability of the feature.
By releasing features early in the incubating state, users gain a competitive advantage through early access to new functionality in exchange for helping refine it over time, ultimately making Gradle a better tool.
To learn more, see the User Guide chapter on the Feature Lifecycle.
This release introduces a new mechanism for publishing to Ivy repositories in the Ivy format. It also introduces some new general publishing constructs. This new publishing support is incubating and will co-exist with the existing methods for publication until the time where it supersedes it, at which point the old mechanism will become deprecated. The functionality included in this release is the first step down the path of providing a better solution for sharing the artifacts built in your Gradle builds.
In this release, we have focussed on laying the groundwork and providing the ability to modify the Ivy module descriptor that is published during a publish operation. It has long been possible to fully customise the pom.xml
when publishing in the Maven format; it is now possible to do the same when publishing in the Ivy format.
The new functionality is provided by the 'ivy-publish
' plugin. In the simplest case, publishing using this plugin looks like…
apply plugin: "ivy-publish"
// … declare dependencies and other config on how to build
publishing {
repositories {
ivy {
url "http://mycompany.org/repo"
}
}
}
To publish, you simply run the “publish
” task.
To modify the descriptor, you use a programmatic hook that modifies the descriptor content as XML. This is the same approach that you take in Gradle when modifying IDE metadata XML or Maven POM XML content.
publishing {
publications {
ivy {
descriptor {
withXml {
asNode().dependencies.dependency.find { it.@org == "junit" }.@rev = "4.10"
}
}
}
}
}
In this example we are modifying the version that is expressed of our junit
dependency. With this hook, you can modify any aspect of the descriptor. You could for example easily build a functionality similar to Ivy deliver on top of this in conjunction with the new Resolution Result API. In general, it can be useful to optimize the descriptor for consumption instead of having it be an accurate record of how the module was built.
For more information on the new publishing mechanism, see the new User Guide chapter.
Gradle has long shipped with HTML report functionality for JUnit test results that improves on the Ant default. It is now possible to use the same HTML report format for TestNG test results. See the reports generated by the Gradle automated builds as an example of the new improved report.
The reports are not yet turned on by default. To enable the new TestNG test reports, simply set testReport = true on your test task.
Note: The new report might exhibit increased heap usage for tests that log many messages to the standard streams. You can increase the heap allocated to the test process via the jvmArgs property of the test task.
Gradle currently supports two different Java compiler integrations: A native Gradle integration that uses the compiler APIs directly, and an Ant-task based implementation that uses the <javac>
Ant task. The native Gradle integration has been the default since Gradle 1.0-milestone-9. Some of its advantages are:
The Ant-task based integration has now been deprecated and will be removed in Gradle 2.0. As a result, the following properties of CompileOptions
are also deprecated and will be removed in Gradle 2.0:
useAnt
optimize
includeJavaRuntime
Gradle currently supports two different Groovy compiler integrations: A native Gradle integration that uses the compiler APIs directly, and an Ant-task based implementation that uses the <groovyc>
Ant task. The native Gradle integration has been the default since Gradle 1.0. Some of its advantages are:
The Ant-task based integration has now been deprecated and will be removed in Gradle 2.0. As a result, the following properties of GroovyCompileOptions
are also deprecated and will be removed in Gradle 2.0:
useAnt
stacktrace
includeJavaRuntime
The ArtifactRepository
type has a setName(String)
method that you could use to change the repository name after it has been created. Doing so has been deprecated. The name of the repository should be specified at creation time via the DSL.
For example:
repositories {
ivy {
name "my-ivy-repo"
}
}
// The following is now deprecated
repositories.ivy.name = "changed-name"
A deprecation warning will be issued if a name change is attempted. It has been deprecated because changing the name of a repository after it has been added to the container can cause problems when tasks are automatically created for created repositories.
The entry point to the ResolutionResult API has changed. You now access the ResolutionResult via configuration.incoming.resolutionResult. New convenience methods were also added to the API. For more information please refer to the javadoc for ResolutionResult.
Compile
task type removedThis was replaced by CppCompile
in Gradle 1.2. You should use the replacement class instead.
GppCompileSpec
properties removedThe deprecated task
property was removed from GppCompileSpec
.
The default value of the testReport property value of Test tasks has been changed to false
for TestNG. Previously, this property was ignored when running with TestNG - the html results were generated regardless.
This property now enables/disables the new improved TestNG report introduced in this release.
This was an early contribution that did not work and was an undocumented private type.
org.gradle.api.publication
packageThis package contained some early experiments in a new publication model. It was incomplete and undocumented. It is superseded by the new publishing functionality introduced in this release, so has been removed.
We would like to thank the following community members for making contributions to this release of Gradle.
test.debug
to false
when using test.jvmArgs
(GRADLE-2485)application
plugins generated shell scripts (GRADLE-2501)PATH
env var is not set (GRADLE-2461)We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.