Transitive strict dependency declaration ignored by Gradle

You seem quite knowledgeable on the topic, so maybe you could help me out: I have an application (“app”) which depends on a utility library (“util”) of a specific major semver version. Then I have another dependency (“do-stuff”) which internally also depends on the same utility library (“util”), but on another semver version, meaning there is a breaking change. Even though “do-stuff” declares its dependency on “util” strictly (via the implementation configuration), this is ignored by Gradle, leading to a runtime crash when “app” calls a method in “do-stuff” which uses “util” internally, as there have been breaking changes.

So far, I have not been able to find a solution for this problem, except for bundling the version of “util” that “do-stuff” depends on into the jar of “do-stuff” with the shadow plugin while leveraging its relocation capabilities.

How would I go about fixing this problem?