Force transitive dependency version in Gradle - maven

I'm playing around with gradle trying to port my maven project and here's my problem:
In maven we have the <dependencyManagement> which provides a common (default) version for certain dependencies (which is used only when in a sub-pom this artifact is used without a version number). It also, from what I understand, forces a certain version for all transitive dependencies. So if I understand correctly even if artifact B which we have as a dependency has a dependency on artifact C version 1.0 then we will still use a version of artifact C defined in the <dependencyManagement> (so it might be 2.0). Is that correct?
If so then is there a way to do something similar in Gradle? I know that a common way of replacing the <dependencyManagement> is to simply create a Groovy map in one of the build scripts. But how can I force the transitive dependency version? If I use Gradle's "force" won't it affect all (not only transitive) dependencies (which is obviously not what I want)?

In Gradle, forcing a version (e.g. with Configuration.resolutionStrategy.force) will force it for all dependencies of the configuration, direct and transitive. There is no first-class feature that forces a version only for transitive dependencies. Do you have a valid use case for this? At the end of the day, both Gradle and Maven will select a single version for a dependency anyway, no matter where and how often it appears in the dependency tree.

There is a ResolutionStrategy feature that allows forcing artifacts versions including transitive dependencies: https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
It is also possible to configure dependencies constraints: https://docs.gradle.org/current/userguide/dependency_constraints.html

Related

Comparing Maven project dependencies

Is there a simple way to list the differences between the artefacts added to the classpath by one version of a Maven project and another?
Here is the problem I'm trying to solve. If I change the version of an artefact declared in a Maven project, the list of transitive dependencies added to the classpath by the dependency may change. I want know what those changes are before I commit a change to a dependency version. The primary reason I want to know what transitive dependencies will change on the classpath when I change the version number of declared dependency is concern that changing the version number of a declared dependency may cause the version of a transitive dependency to change to one that has a security vulnerability in it.
At the moment, I'm using the dependencies plugin tree goal to produce a before and after change dependency tree and then comparing the two by eye. This is not ideal.
I also know of a way to achieve my goal using the OWASP dependency check Maven plugin but this also seem not ideal.
Can anyone suggest a better solution to my problem that using the dependencies plugin or the OWASP dependency check plugin? Is there a Maven plugin to produce what I need?
Thanks
Please try
mvn dependency:list
It will list all the dependencies with version information.
now you can see the difference using any diff checker tool online.

Display updates for Maven transitive dependencies

Say I have a POM which declares a handful of dependencies in some scope (test in my case but should not matter). These in turn pull in a rather larger number of transitive dependencies. I have the requireUpperBoundDeps Enforcer rule active to ensure that every such transitive dependency is at the newest version required by something “above” it.
My goal is to ensure that every dependency in this tree is at the latest available version (which will sometimes be newer than any stated dependency requirement), while keeping the POM as short as feasible. How can I do this?
mvn versions:display-dependency-updates shows only updates available to immediate dependencies, it seems. I recall that there is an Enforcer rule available to force all dependencies to be explicit, which would solve the issue but at the cost of making the POM much longer—redundantly specifying every transitive dependency, even when it would have been determined to be the currently latest version anyway.
Is there a variant of display-dependency-updates that also processes transitive dependencies?

How two know when a maven project has the same transitive dependenciy twice of different versions?

I have to add a new dependency to a maven project. This dependency has four transitive dependencies(according to http://mvnrepository.com/) and between them, there is spring-data-jpa jar.
The maven project I am working in has many dependencies configured in the pom so I understand there could be a big possibility that there is already a spring-data-jpa dependency in the project(transitive or not).
When you work in a large project with many dependencies and you have to add a new one, how to check if there is already the same transitive dependency of a different version? I have to check manually the transitive dependencies for each direct dependency configured? Has maven a warning for this situation?
How maven works in this situation? I mean, there could be two spring-data-jpa jars of different versions(this would be a problem) or maven resolves this in another way?
The simple answer is that the dependency plugin can tell you. The longer answer is that there are a number of different situations to consider about transitive dependency management, and how the plugin helps and what to do about it differs for each one.
Maven automatically chooses which dependency to include if two dependencies have the same coordinates (groupId, artifactId) with different versions. Broadly speaking, it picks the version that's highest in the tree - effectively overriding dependencies defined in downstream transitive dependency poms. So, if you have two different versions of exactly the same dependency then you will still only find one version of the dependency on the relevant classpath.
The dependency plugin can help you identify this situation by highlighting points where its made a decision, but you probably want to use the dependencyManagement section of your top-level pom to ensure that the dependencies which you bring in are the ones you expect.
Separate difficulties can arise when a dependency changes its groupId or artifactId. Then you can get two dependencies on the classpath - one with an old version on the old coordinates and one with the new version on the new coordinates. As examples, Spring, Hibernate and Apache commons have all found themselves doing this at some point or another. In this case all you can do is use to the dependency plugin to identify duplicated dependencies and then use exclusions tags to explicitly exclude them as transitive dependencies from the dependencies which are pull them in.
It's important to note that all of this dependency management can cause unintended breakage. If the thing that your application depends on really does depend on some specific version of a package as a transitive dependency then you can break it by overriding that version. So testing the features that you use is essential.
Have you tried the Maven Dependency Plugin? There's some useful goals you can run, such as mvn dependency:tree etc.

Maven direct and transitive dependencies resolution

Artifact_A has both the direct dependency and the transitive dependency on Artifact_B within the same scope.
Does the direct dependency always precede the transitive dependency, or the one of higher version prevail?
Is there any reference with better illustration on Maven Dependencies Resolution than the chapter Maven reference manual - Project Dependencies?
The dependency-resolution mechanism can be complicated. If there's a managed version (dependencyManagement), then that will take precedence. Generally speaking, Maven will use the highest-requested version that satisfies all of the requirements (for example, some servlet package might require [2.4,3.0) while another package requires 2.5, so Maven will use 2.5). If Maven can't find such a version (in the above sample, if the second package required [3.0,4.0)), then it will produce an error.
If you have a specific issue that you're running into, feel free to post a question with all the details.

Is there a way to disallow dependencies on certain artifacts in Maven?

I have a problem with the maven artifact for junit. It comes packaged with hamcrest, but I like to use a later version of hamcrest, so my projects need to use junit-dep and exclude the hamcrest dependencies.
I have a parent pom.xml with a dependencyManagement section to handle the version of junit-dep that I want and ensure that hamcrest is excluded. However, I'm constantly running into an issue where some other test library includes a transitive dependency to junit.
Note that it's not the version number that's a problem. It is the particular artifact. I don't want junit, I want junit-dep. Is there any way to say in my dependencyManagement (or anywhere else) that I never want to include junit of any version at all?
Unfortunately, there is no global exclude option in dependency management.
On the other hand, if you don't want JUnit jar do be included ever, you may play the same trick as commons-logging-99.0-does-not-exist.jar.
Here is the link that describes the trick -> http://day-to-day-stuff.blogspot.com/2007/10/announcement-version-99-does-not-exist.html
Personally, I've found out that it's easier to do the job by using <exclusions> tag.

Resources