We’ve lived, somehow, without addressing this directly but it has now become a problem that requires Gradle expertise beyond my own. I recognize that out project setup is NOT ideal but I don’t know how to change it.
I searched online and found some mentions of similar issues, some answered briefly, others not at all, such as:
Our current setup is based on what I read about somewhere long time ago and feared a bit, but we lived… so far. We have one *.gradle file that declares our third party dependencies as essentially string forms of dependenices or arrays of those. It is essentially a file of constants. we declare actual project dependencies from those projects’ build.gradle files by referencing those constants.
Since there is some inevitable version disagreement between our transitive dependencies we do rely on Gradle “deciding” to use the newest of the versions. In some cases we had to force the versions but this, we realize, is unmaintainable. However, as different (sub)projects have different dependencies, they see those conflicts resolved differently and we end up with one project using one version of some jar and another project uses another version of the same jar.
This causes problems when we try to package up our product as we end up with all jar versions competing for a spot in the resulting distribution bundle, unless we do something about these. Problem is also in Eclipse, where we try to use consistent versions and have attempted to have any one jar be a part of as few classpaths as possible - i.e. if it is inherited from a dependency project, it should not be re-declared as a dependency. Problem is that they may differ by version only. This causes problems if the classpath order happens to be the wrong one (older version before the newer version) and affects product startup that involves classpath scanning for various reasons.
I thought of creating a project that will be there ONLY to declare all dependencies. It would essentially replace our constants gradle file I mentioned above, having separate configuration for each and every dependency that any of the ‘real’ projects need. Real projects would then only be allowed to declare dependencies onto these configurations of this special ‘third party dependencies holder project’.
However, I am not sure that is the correct way either or that it would work. For one, it forces further centralization of all dependencies, instead of encapsulating them within the projects that need them. Perhaps more problematically, I am not sure this would solve anything depending on when the transitive dependencies are resolved.
We are presently still on gradle 2.4 but would upgrade if there is some help in newer versions.