I would like to implement a rule in Gradle which makes the build fail when a conflict resolution exist between 2 incompatible semver versions of a module. This means it should fail when the major version differ between the 2 candidates (1.0.0 vs 2.0.0).
I did not find any plugin allowing to do that.
I tried to find a way to plug my custom rule but with no luck until now. Looking at the Gradle source code I guess I should extend a ModuleConflictResolver or a ModuleConflictHandler but I can’t find a place to inject my custom class. It looks like it is not designed to be customizable.
As a workaround, I added a DependencyResolutionListener and relied on the selection reason of the ResolvedComponentResult to extract the 2 conflicting versions. This means parsing the message “between versions a.b.c and x.y.z”, which is quite ugly and fragile…
Is there a better way to do what I want?
Related
Gradle is working on new features for sharing dependency versions between projects that will provide central locations (settings.gradle, libs.versions.toml) for declaring common dependencies.
It's already possible (and easy) to share a dependencies block through a plugin, so what is the downside of the plugin approach to sharing dependencies, versus the new version catalogs and dependency bundles? What do these new features improve upon?
This is not a thorough answer. However, let me share what I think makes a difference. We need to keep in mind that Gradle is built around developer productivity and making builds as fast as possible.
Centralizing common dependency declaration makes sense to be supported out of the box. Currently, there is a good chance that when you look at different Gradle projects, each one of them may implement a different approach to this. Cédric Champeau iterates over some existing pattern in this blog. Having a standard solution makes it easier to get started as developer. Cédric further states
Long story short: the presence of a catalog makes discoverability and maintenance easier, but it doesn’t remove any of the flexibility that Gradle offers. We’re thinking about ways to enforce that all direct dependencies are declared via a catalog in the future.
Declaring dependencies in libs.versions.toml allows Gradle to skip build script compilation when dependency versions are changed. This is significantly faster than changing the same in a script plugin. As a side-effect of declaring dependencies in libs.versions.toml, we may see third-party tooling that update dependencies automatically in the future.
I have created a library, which is distributed with maven. Right now I would like to add new library as a dependency, which size is more than 8 mb.
I want to make that dependency as optional and this is why I think that creating a different library flavor would be correct way (might be wrong, I would be open to other solutions)
However, I searched and found that I can't do that with libraries..
Maybe something changed, or is there a different way to implement optional dependency to library, which should be managed by the user who integrates my library. I would like to keep same dependency name in order to maintain only single version of library.
Thanks in advance :)
In a gradle file it's possible to specify a dependency with a dynamic version, like:
compile 'some.dependency:name:1.+'
This is documented to resolve the "newest" matching version. I have two questions:
[1] What does "newest" mean? Suppose the available versions are:
1.0
1.1-beta
1.1
Is the "newest" one 1.1-beta or 1.1? Does it depend at all on when the versions were published, or is it purely based on the version strings? If purely based on the strings, what ordering is used, because if it's just alphabetical then I think 1.1-beta would end up being "newer" than 1.1.
[2] As a publisher of a module, is there a sensible way of publishing a beta build such that developers who are depending on your module and using dynamic versions wont automatically pick it up? Is there a standard or recognized way of doing this?
Thanks!
[I'm aware using dynamic versions is discouraged. These questions are from the point of view of someone providing a module, and wanting to ensure that developers who do use it and ignore this advice still don't end up pulling in something unexpected]
I' m guessing you are publishing to maven, and as I know, there should be an xml file named maven-metadata.xml which holds the information of the latest upload to the corresponding artifact. So I guess it does not depend on your naming convention but what you upload the latest. If you would upload 1.0.0.1 the latest then it would be downloaded not 1.1-beta or 1.1 versions.
For more info check here.
I'm looking for information about Gradle dependencies, similar to this question:
What is the Gradle artifact dependency graph command?
but with a narrower scope. I'm wondering about functionality that Maven has for analyzing dependencies, and whether or not Gradle includes something similar. Specifically, Maven can scan your source code and then compare that to your declared dependencies, and determine (roughly) if you have dependencies declared that you aren't using and/or if you're using dependencies that you haven't declared (due to issues related to Turing completeness, this analysis may include false positives/negatives, but I generally find it to be incredibly useful regardless). Does Gradle have anything similar? So far I haven't been able to find anything.
Such a thing is not shipped with Gradle at least as far as I know.
You best bet is to search through Google and / or plugins.gradle.org for finding a plugin that does what you want.
I for a short period did this for you and found this one which might be what you want: https://plugins.gradle.org/plugin/com.intershop.gradle.dependencyanalysis
I have no idea about its quality or anything, I just searched through plugins.gradle.org, I don't know or ever used that plugin.
I am working on migrating multi module java project into maven. Now for most of them i migrated to maven.
Finally i am aware my project have lot of unnecessary jars included, and i want to clean them up.
I know maven has plugin command, mvn dependency:analyze. Which works very well.
dependency:analyze analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared. based on static code analysis.
Now my question is that, how can i remove reported unused and declared dependency for cleanup purpose. It could be possible those jars were getting used at runtime and my code will compile perfectly fine after removing but blow up at runtime.
An example: mycode compile with one of opensource library antisamy.jar but it require batik.jar at runtime. And mvn dependency:analyze reports me to remove batik.jar.
IS my understanding correct or i need expert inputs here.
Your understanding seems to be correct.
But I'm not sure why you'd think that there is a tool that could cover all the bases.
Yes, if you use stuff by reflection, no tool can reliably detect the fact that you depend on this class or the other.
For example consider this snippet:
String myClassName = "com." + "example." + "SomeClass";
Class.forName(myClassName);
I don't think you can build a tool that can crawl through the code and extract all such references.
I'd use a try-and-fail approach instead, which would consist of:
remove all dependencies that dependency:analyze says are superfluous
whenever you find one that was actually used, you just add it back
This could work well because I expect that the number of dependencies that are actually used by reflection to be extremely small.