Transitive dependency locking

I tried Gradle 4.8’s dependency locking. It only listed coordinates for explicitly listed dependencies, but not for their transitive dependencies, in files under gradle/dependency-locks.

Is there any way to also lock transitive dependencies?

I can think of some situations where warning about changing transitive dependency versions would be useful, e.g.:

  • if I currently depend on artifact A 1.0, which has a transitive dependency on X 2.0, and if X is not anywhere else in my dependency graph, then Gradle will use X 2.0. If I subsequently add a dependency on artifact B 1.0, which has a transitive dependency on X 3.0, then I would assume that Gradle would start using X 3.0. Would dependency locking warn that X was bumped from 2.0 to 3.0? Or would that not warn since the coordinates for X are not in the lock file?

  • the same coordinates (including version) resolve to different artifacts in two different repos. The artifact in repo 1 has a transitive dependency on X version 1.0, but the artifact in repo 2 has a transitive dependency on X version 2.0. If I switch from repo1 to repo2 in my build, would dependency locking warn about this change?


Dependency locking locks first level and transitive dependencies. Exactly for the reasons you outlined here.

To answer your questions:

  • Gradle would fail the build, as a dependency was added, you would need to update the lock state.
  • Gradle would fail the build as the dependency resolution would result in a different graph. Note that what you highlight here is a serious metadata problem though, and dependency cache can play tricks if you are not careful.

If that is not the case for you and you have a reproducible test case, please share it.

The dependency cache is repository sensitive, so if you switch it would recheck and notice that the pom is is different. It won’t “play tricks” :slight_smile:

Thank you both for the insight.

It sounds like transitive dependency locking depends on the cache.

Does this mean that if I clone a repo with dependency locking enabled to a completely clean machine (e.g., no dependency cache, gradle cache or maven cache, etc.), then Gradle won’t be able to verify that the transitive dependencies are the same as those used on another machine when it generated the dependency locks?

Would it makes sense to add an option to include transitive dependencies in gradle/dependency-locks files? Or should this always be enabled?

Does dependency locking just check the coordinates & metadata (e.g., POM, .module, Ivy XML, etc.) or does it also check artifact file contents (possibly using size & hash combo)?

If it does the latter, would it be useful to add the contents info to the gradle/dependency-locks files, so you can compare artifacts without already having them in your cache?

You must have misunderstood my answer. It doesn’t depend on the cache. The cache is totally transparent.

The lock file should contain all versions (if it doesn’t that would be a bug). It does not contain hashes because verifying file integrity is a different concern from locking versions.

I mistakenly thought that Gradle didn’t lock transitive dependencies because all my dependencies included ext = "jar", which prevents inclusion of transitive dependencies. I didn’t know that, however, so I experienced many issues where Gradle didn’t seem to handle transitive dependencies as the docs suggested it would. So all is working correctly now. Thanks for the help.

1 Like