Dependency resolution features in Gradle 1.0-milestone-8

We’ve added some cool new dependency resolution features to Gradle-1.0-milestone-8. We think these new features are pretty compelling, and we hope you find them useful.

Offline support It’s been oft requested and a long time coming, but Gradle now has full support for building while network resources are not available. If you run your build using the ‘–offline’ flag, Gradle will use cached dependencies if they are available, and fail the build if they are not.

When running offline, Gradle will always use cached results for a dynamic version or changing module, even if the cached results have expired. This is similar to running with very long cache expiry timeouts, except that Gradle will fail-fast if a dependency is not available in the cache, rather than attempting to download it.

Refresh dependencies Whether using Maven or Gradle, it has been common practice to delete files from the cache in order to force them to be re-downloaded. Well no more! Gradle-M8 introduces a new ‘–refresh dependencies’ switch, that tells Gradle to ensure that all dependencies are up-to-date. This can often be achieved without re-downloading the dependency artifacts at all.

The way this works is that Gradle will first check for an SHA1 checksum file on the remote server, and compare that published checksum with any previously downloaded artifacts. If the checksums match, Gradle will use the cached artifact, otherwise Gradle will download the new artifact.

If no SHA1 checksum is published, ‘–refresh dependencies’ will cause Gradle to download the remote artifact.

The same mechanism is used by Gradle to check for updated Maven SNAPSHOTs and other changing modules. So it’s important to publish .sha1 files for all of your artifacts to avoid unnecessary downloads.

This is also a great feature to make sure that your application can be built with your current remote repositories and the local cache is not hiding any problems. For example in the case someone has accidentally removed a required dependency from a remote repository which is already in the local cache of your CI machine. Running a nightly CI build with the refresh option enabled would alert you about the misconfiguration of your repositories, without requiring the cache to be deleted.

Reusing the M2 cache Building on the same mechanism as ‘–refresh dependencies’, Gradle now attempts to reuse artifacts in your local Maven repository rather than downloading them anew. If Gradle is asked for a module artifact that is not in the Gradle cache, it will look in the M2 cache for candidate artifacts with the same name and version. If a candidate is found, Gradle will compare the published .sha1 checksum with the calculated checksum of the candidate, using the candidate if it matches.

Imagine you run a Gradle build that requires ‘junit:4.10’. You’ve previously downloaded this via Maven, but you’ve never asked Gradle for this module before, so it’s not in the Gradle cache. Before downloading the jar, Gradle will find ‘junit-4.10.jar’ in ‘.m2/repo’ and compare the checksum of this jar with the remote ‘junit-4.10.jar.sha1’ file. Oftentimes there will be a match, and Gradle won’t need to download the remote jar file at all.

The matched candidate artifact is then copied from the local Maven repository into your Gradle cache, so there’s no issue if you want to later delete your Maven install :-P.

Avoid mavenLocal() - Now that Gradle can reuse artifacts from the M2 cache, we feel that it is generally NOT a good idea to add mavenLocal() to your list of repositories. The exception is when your build depends on artifacts locally published by Maven. Including mavenLocal() in your build script can mean that your build script is not portable. A required dependency that is in your local maven repo may not be present in that of another developer, so what works on your machine may not work on another’s.

Improved logging Sometimes you want to know what Gradle is doing to resolve your dependencies; where is Gradle looking and what is it finding?. Running Gradle with ‘–info’ will now log all of the remote HTTP requests made by Gradle during dependency resolutions. Combine this with the new ‘–refresh dependencies’ switch, and you’ll see exactly where Gradle found all of your dependencies. Nice!

More documentation As well as the new features, there is a new section in the user guide describing our dependency cache in detail. Check it out at Learning the Basics.

I really like the offline feature :slight_smile: