Gradle 1.0 is a major step forward in the evolution of Gradle, and build tools in general.
Here are the new features introduced in Gradle 1.0, including the changes in all of the milestones.
Dependency management is at the heart of every build. In Gradle 1.0 we've moved away from using Ivy for dependency resolution. The dependency resolution engine has been rebuilt from the ground up; it is now faster, more accurate and more flexible.
With full DSL support for Maven and Ivy repository formats, offline builds, the ability to refresh dependencies, and better control over version conflict resolution, we feel that Gradle 1.0 raises the bar for dependency management in build automation. As we continue to innovate in this space, we plan to take the dependency management that works so well for Java and adapt it to other languages and technologies.
You're not always connected to a network; Gradle 1.0 helps you out when you're offline. When run with the --offline
command-line option, Gradle will use whatever cached dependencies are available, failing early if a required dependency is not available in the cache. For Maven snapshots, changing modules and dynamic versions the most recent cached result will be used; no attempt will be made to connect to the network for dependency resolution.
When run with the --refresh-dependencies
command-line option, Gradle will validate all dependencies against the repositories declared for you build, downloading anything that is not up-to-date. As well as ensuring that you have the latest version of all dependencies, this process will check that every required dependency is available in a defined repository; just having the dependency in your local cache is not sufficient and will lead to a build failure.
The --refresh-dependencies
option is particularly helpful when things go wrong with dependency resolution; like when you are setting up a new repository and don't get it exactly right the first time. In such a case, being able to refresh your dependencies without deleting them from your cache directory can be very useful.
Dependency validation utilises the Gradle change detection algorithm for remote repositories, so artifacts that are unchanged from the cached version will not be re-downloaded.
When your dependencies are resolved, the transitive dependency set may bring in several different versions of the same module. By default, Gradle's conflict resolution will use the newest version. This is useful in most cases, but sometimes it isn't what you want, so Gradle 1.0 gives you control over the process by:
The options for handling resolution conflicts will continue to improve, giving users of Gradle full customization of the conflict resolution behaviour.
While it is still possible to supply an Ivy DependencyResolver to locate your dependencies, in Gradle 1.0 we've improved our repository definition DSL to make it easier to declare the Ivy and Maven repositories you use for dependency resolution. Using the repository DSL to specify your repository type, location, layout and credentials is now simple and consistent.
Gradle has always made it easy to publish the default artifacts generated by your build, but it was not always trivial to publish additional files that weren't generated as a standard archive. Gradle 1.0 introduces the ability to publish file-based artifacts that are not produced by an archive task, simplifying the process of publishing arbitrary files to your repository.
Sometimes dependency resolution is a black box to the end user. We've attempted to make the whole process more understandable by improving the documentation, log messages and error reporting.
We've improved logging of dependency resolution; running Gradle with --info --refresh-dependencies
will track all remote repository requests, helping to shed light on what's going on behind the scenes.
In Gradle 1.0 we've replaced the ivy artifact cache with our own implementation, targetting performance, consistency and reliability. Our new cache has advanced features that help avoid subtle (and not so subtle) problems permitted by other cache implementations, where a build that runs correctly on one machine fails on another.
The Gradle dependency cache remembers the origin of every dependency it holds, so your build can only access cached dependencies that come from a repository defined for your build. It is not possible for the presence of a cached artifact to mask the fact that a dependency is not available. This helps to ensure that your build will run correctly in any environment.
There is no longer any need to declare separate user home directories or cache locations for different projects; the Gradle 1.0 dependency cache is fully thread-safe and multiprocess-safe.
To reduce the number of downloads required, Gradle 1.0 has an improved algorithm for detecting if a cached artifact is up-to-date. By using published .sha1 files, ETags, and last-modified-date + content-length, Gradle will do everything it can to check if the version on the server is the same as the version you have already downloaded.
If you're a maven user, in many cases the dependency you require is already available in your local m2 repository. To save downloading the dependency again, Gradle will reuse any locally available artifacts if they match the checksums published by a remote repository.
To improve performance, by default Gradle 1.0 will cache the resolved value of dynamic versions and changing modules for 24 hours. You can easily manage this timeout using the new cache-control DSL.
The cache-control DSL is a work in progress; in the future Gradle will allow full programmatic control of all aspects of caching.
You can find out more about the Gradle dependency cache in the User Guide chapter and this series of forum posts: part 1, part 2, and part 3.
A fast build means faster feedback. Gradle 1.0 includes a host of performance improvements.
We've also enhanced the Gradle profile report, which now includes dependency resolution times in an improved layout.
We've done a lot of work to make dependency resolution as fast as possible, while staying reproducible and accurate.
To do this we:
Faster dependency resolution also means faster up-to-date checks for speedy incremental builds.
We've done a lot of work stabilising the Gradle daemon, and it is no longer marked as experimental. The Gradle daemon reduces the startup time of every gradle
invocation, and we recommend it for all developer builds.
By default, Gradle 1.0 no longer uses Ant tasks for Java and Groovy compilation. By removing the task overhead, in-process compilation has been made faster.
When configured to compile in a separate process (compile.options.fork = true
), Gradle will now use a single daemon compiler process to further speed up the compilation of your source files. This means that the compile process only needs to be forked once per build invocation, dramatically reducing compile times for large multi-project builds.
By reading cached history more efficiently for large set of input and outputs, Gradle 1.0 performs up-to-date checks faster for large sources sets. With faster up-to-date checks your incremental builds will be faster, reducing the time to re-build when little has changed.
When run with the --profile
command-line option, Gradle will generate a report detailing the breakdown of time spent executing your build, including dependency resolution time. This report can provide hints about the critical things that slow down your build, helping you make your build faster.
Gradle has always provided great out-of-the-box support for standard Java applications. With Gradle 1.0 we've included a number of new code quality integrations to make it easy for you to include these important tools in your build process.
Supported tools include:
Using the Gradle Sonar plugin, you can now easily integrate your build results with Sonar, the web based platform for monitoring code quality.
FindBugs uses static analysis to look for bugs in Java code. The Gradle FindBugs plugin adds a task for every source set to scan the Java bytecode for a list of bug patterns.
JDepend allows you to generate design quality metrics, by analyzing the coupling between Java class files. The Gradle JDepend plugin adds Gradle tasks that analyze all inter-package dependencies of a source set, producing a report that can help you to find unexpected couplings, package dependency cycles, and refactoring targets.
The popular PMD project provides tools to inspect Java source code looking for potential bugs, inefficiencies and duplication. The Gradle PMD plugin adds a task that will produce a PMD report per defined source set. The plugin provides many configuration options, including the ability to define custom rulesets, and which version of PMD to use.
You can now apply the Gradle Checkstyle plugin and the Gradle CodeNarc plugin separately to your build. Both of these plugins have been improved to provide more flexibility, and you can now specify exactly which version of each tool to use.
Whether you develop code in Eclipse STS, Intellij IDEA or NetBeans (experimental), there is a native Gradle integration for your IDE. Using native IDE integrations you can import and run Gradle builds directly into your IDE, and keep your IDE settings in sync with your Gradle build definition. While not strictly part of the Gradle distribution, these native integrations continually improve as Gradle provides more features via the Tooling API - the new embeddable API on which these integrations are based.
If you don't require tight native integration, the Gradle IDE plugins help you by generating standard project files for your environment. We've improved these IDE plugins to provide more configuration options, to have better defaults, to run faster and to smoothly configure your IDE for your Gradle project.
The new Gradle IDE plugins generate IDE project files based on the project defined in your Gradle build file. The Gradle Eclipse plugin makes it easy to keep your .classpath and .project files in sync with your Gradle build, while the Gradle IDEA plugin does the same for your .ipr and .iml files.
As usual with Gradle, you have full programmatic control of the generated model. The DSL reference for the idea and eclipse plugins contains many code samples, demonstrating how to fine-tune the configuration and ensure your project imports easily into the IDE.
You can now import Gradle projects and run Gradle builds directly inside of Eclipse, using the Eclipse STS Gradle plugin. We are very grateful to our friends at SpringSource for making this possible, and we continue to collaborate to make this integration even better.
Using the Intellij IDEA Gradle plugin you can easily import an existing Gradle project directly into Intellij IDEA, with many more features planned in the near future. Many thanks to JetBrains for their continued development of this plugin.
The NetBeans Gradle plugin provides the ability to import and run Gradle build files directly in NetBeans. Thanks to the NetBeans team for developing this plugin.
This NetBeans integration is still experimental, but we hope that by leveraging the power of the Gradle Tooling API the plugin will continue to evolve and improve in the future.
Gradle 1.0 sees the introduction of the Gradle tooling API, a new way to embed Gradle. This API allows you to execute and monitor builds, and to query for details about the build. The Tooling API takes care of downloading the version of Gradle required to execute a particular build, and utilises the Gradle daemon process for lightning fast command execution.
The Gradle Tooling API operates in a version independent manner, meaning that any given version of the Tooling API is able to execute builds using both newer and older Gradle versions. Your Gradle version isn't tied to the version of the Tooling API being used, allowing tools like the native IDE plugins to remain stable while supporting a wide range of Gradle projects.
The Gradle Tooling API implementation is lightweight, with only a small number of dependencies: you don't need the Gradle distribution to use the Tooling API. As a well-behaved library, it makes no assumptions about your class loader structure or logging configuration. These reasons ensure that the Gradle Tooling API is easy to bundle inside your application.
Using the Gradle Tooling API allows you to execute builds using many different versions of Gradle: the version of the Tooling API is not tied to the version of Gradle executing. This cross-version compatibility is constantly verified by our extensive test suite, which validates the correct function of Tooling API features across all Gradle versions. What's important is that we don't just test backwards compatibility but also forward compatibility, so you can be sure that you'll be able to run a build using Gradle v1.1 even if you're using Tooling API v1.0.
The Gradle build daemon reduces the startup and execution time of builds by running them in a long-lived daemon process. The gradle
command becomes a client process that communicates with the daemon process, avoiding various JVM startup costs and giving the JVM an opportunity to optimize hotspots.
Gradle 1.0 brings a host of improvements to the daemon, and we now recommend it for all developer builds.
In earlier versions of Gradle, the daemon was considered an experimental feature. Much work has gone into stabilizing the daemon since it was introduced and we are now recommending it for all developer builds. There are still many improvements planned in the upcoming Gradle releases, but we believe that most of the stability issues have been resolved.
While you can explicitly enable the daemon for a particular build execution with the --daemon
command-line option, the best way to make the daemon your default is by configuring the org.gradle.daemon property.
Some builds consume the standard input, for example, to perform the interaction with the user. The daemon fully supports those kinds of builds, by forwarding any client input to the executing build process.
The java version the daemon uses is configurable. In case you run different builds with different java versions multiple daemons will be spawned to avoid compatibility issues.
Longer term, the daemon will offer even more features that improve the performance of your build. Performing up-to-date checks, dependency resolution and project evaluation pre-emptively are just some of many planned features. The Tooling API - an official way to embed Gradle - fully takes advantage of the build daemon.
Working at the enterprise scale means more than just a fast build. Gradle 1.0 adds capabilities to help you push build logic and configuration out to developers and across teams in a controlled way.
Gradle enables zero-configuration on the client side. Any necessary configuration, be it JVM args or repository definitions, can be specified per project, team or enterprise and stored in version control. Bundle these definitions into a corporate plugin and distribute with the Gradle wrapper for a powerful way to manage your enterprise build environment. No more complex wiki pages explaining how to configure the build on a new machine. No more wasted time due to false alarms caused by a development machine or CI job incorrectly configured.
Making it easy to administer the enterprise build environment was a core goal of Gradle 1.0. We will continue to innovate in this area in future releases.
The Gradle wrapper is invaluable in a large team to guarantee that a particular Gradle version is used to execute your build. This provides a consistent build environment, enabling reproducible and maintainable automation.
The Gradle wrapper automatically downloads and installs the required Gradle distribution, just checkout the project from version control and run. No previous install of Gradle is required! Upgrading to a new version of Gradle is trivial with the wrapper. Increment the version number in your wrapper configuration script, and anyone running your build will automatically switch to use the new Gradle version.
In many cases your build will only execute on a particular java version, or with certain memory settings. Rather than having developers tweak their local environment to run your build, Gradle allows you to explicitly configure the JVM args and Java location for your build. These settings can then be checked-in to version control and become part of a versioned build environment, improving the maintainability and consistency of the development environment.
The build environment configuration is honoured by both daemon and non-daemon build executions. However, when configuring build environment settings we strongly recommend the use of the Gradle daemon on development machines, to avoid the performance penalty of starting an additional JVM on each build execution.
Using a Gradle init script, it is possible to configure standard plugins, define standard repositories or apply certain common conventions across a wide range of projects. This feature makes it easy to use a particular standard plugin in a project without the hassle of configuring the build script classpath.
Init scripts are very flexible, and may be applied to a single build execution, to all builds run by a particular user, or to all builds executed by a particular Gradle installation. In Gradle 1.0 it is now possible to have multiple init scripts specified, which will be applied to your build environment in a well-defined order.
Many large organisations desire a consistent set of environments, rules or plugins to be applied to all builds in the enterprise. By constructing Gradle init scripts that specify these corporate standards and bundling these with a regular Gradle distribution, you can construct a build tool that specifically enables and enforces your corporate standards. When combined with the powerful distribution mechanism of the Gradle wrapper, a tailored Gradle install can enable you to provide build standardisation across the enterprise.
Gradle 1.0 includes preliminary support for building C++ based projects on both Windows and UNIX like platforms. The cpp-exe
and cpp-lib
plugins can be used for building native executables and libraries respectively from C++ source code.
These plugins are in the early stages of development, but can already be used to generate native binaries.
Currently, there is no direct support for creating multiple variants of the same binary (e.g. 32 bit vs. 64 bit) and there is no direct support for cross platform source configuration (á la autoconf) at this time. Support for different compiler chains, managing multiple variants and cross platform source configuration will be added over time, making Gradle a fully capable build tool for C++ (and other "native" language) projects.
The Gradle development team would like to encourage all users interested in C++ support to experiment with the existing functionality and provide feedback via the Gradle Forums.
Gradle is committed to making it easier for you to develop software. We continue to add new plugins, conventions and features that make the everyday use of Gradle more convenient. More plugins means more build-by-convention support, reduced configuration and less custom build logic.
Gradle now supports several different types of projects: plugins include support for building:
Gradle 1.0 also includes numerous improvements to the build DSL and new features to make your build simpler and easier to maintain.
The Application plugin simplifies the creation of executable JVM based applications. You can use it to run your application directly from your Gradle build, and it will bundle your application for distribution. The packaged application includes automatically generated start scripts for windows and unix systems, third party dependencies and custom distribution files like licenses or documentation.
The Ear Plugin adds support for creating Java EE Enterprise Archives (EAR files). It provides EAR specific dependency management and enables customization of the deployment descriptor.
Digital signatures can be used for tracking build artifacts and files. These signatures allow users to verify who built the artifact and when the signature was created. The Signing Plugin enables the user to:
The Gradle Announce Plugin enables the build to announce custom messages to the user at any or every phase of the build. This feature can work well together with --continue
(see below), by reporting on any failures that occur in a continued build.
The announce plugin integrates nicely with different desktop messaging systems like Snarl, Growl and Ubuntu Notify and also with the internet messaging system Twitter.
It can be annoying to come back from lunch, only to find that your build failed early on checkstyle and never got around to running your tests. The --continue
command line option provides experimental support for continuing a build after a task fails: the end result of the build is the original failure, but the remainder of the build will still execute.
Note that this feature is a work in progress, and is not yet feature complete. In particular, only the first failure is captured and displayed at the end of the build process: you will need to inspect the build output to see what other failures may have occurred in a continued build.
Gradle strives to provide a clean and concise console output, without unnecessary clutter that hides the important things. So by default Gradle does not show the output of the tests on the console. Gradle 1.0 provides a a simple way to display test output on the console. You can also hook in a listener to have full control what test output is shown.
In Gradle 1.0 we're providing better error messages, more documentation and improved samples to help you streamline any troubleshooting. The new extra properties mechanism retains the ability to add ad-hoc properties to your build script, which making it much easier to catch typos.
Naturally there is more work to do, and if you have questions don't hesitate to post them on the Gradle forums.
For details of exactly what was changed in which Gradle 1.0 milestone, please see the release notes of each individual release. You can also consult the migration guide for each milestone release to identify issues that may affect you during an upgrade to Gradle 1.0.
The list of issues fixed between 1.0-milestone-9 and 1.0 can be found here.