Maven dependencies - version vs updates - maven

mvnrepository usually lists "version" and "updates" for each dependency.
If I'm publishing my own package, how do I specify the "updates" version
Which dependancy does Maven used when resolving transitive dependencies? So if my package depends on package A, which depends of package B with - version = 1.0 and updates = 1.1. Which version of B would I get?

You're asking what the meaning of the information in the "Updates" column of MVNRepository's "Compile Dependencies" table is.
It tells you whether there's an updated version of a particular dependency available and if so what the latest version is. If there's a check mark it means the library in question already uses the latest version of dependency X. You will always get the declared version of a dependency no matter what the latest version is.
Hence, if you use valdr-bean-validation 1.1.2 (example above) you'll also get jackson-databind 2.4.0 as a transitive dependency (1st row above). 2.7.1-1 would be the latest available jackson-databind version.
Notes: I finally understand your question. It would have been helpful for you to give us a concrete example right from the start.

Related

Gradle dependency library updated by another library

My gradle has for some time had a dependency on the (amazing) Android library Picasso. It has always been set to version 2.5.2
implementation 'com.squareup.picasso:picasso:2.5.2'
I recently updated all my Firebase libraries from a fairly old version to the latest. At which point something odd happened.
My Picasso method calls began to error
Picasso.with(context)
Which I know from this SO article results from a change to Picasso.
cannot find symbol method with() using picasso library android and I need to change to
Picasso.get()
OK not a big deal, but it got me wondering. Obviously Firebase uses the latest version of Picasso and is making my project use the latest version as well. My question is why is my local gradle file ignored and the newer version of Picasso defaulted to?
Off the top of my head: Since you declare a specific version that requirement is not flexible. To allow for a newer version if available a + declaration is required. My guess is that another dependency is also dependent on Picasso after the updates. Gradle, when given a redundant dependency, will select the newer version.
This is in alignment with what you said, if I understand correctly. If Firebase uses a newer Picasso version, because it requires that version, then Gradle is given two versions to choose one from. This will always result in the newer version being chosen. At least this is default behavior afaik.
It seems to me that you already know Picasso is used by Firebase. If you want to see where which dependency comes from however, you can look into build scans:
gradle build --scan
https://scans.gradle.com/?_ga=2.166196030.1236003146.1565212874-222812074.1565212874
A little bit more advanced dependency management:
1) Set Gradle behavior on dependency conflict:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
2) Declare version constraints (see Rich version declaration):
https://docs.gradle.org/current/userguide/declaring_dependencies.html
You can check the official doc:
Gradle resolves version conflicts by picking the highest version of a module. Build scans and the dependency insight report are immensely helpful in identifying why a specific version was selected.

Maven Version Range - downloads all the available versions not just the latest one

I have two modules: A and B.
A depends from B.
In the module A there is a dependency to B with the following version setting: [1.0.0,)
From the B there are two versions: 1.0.0-1 and 1.0.0-2. The 1.0.0-1 is out of date, it has some missing dependencies, hence I cannot create a build from it. But the 1.0.0-2 is working fine.
When I use the install for the module A I get an error that B:1.0.0-1 has a missing dependency.
That's happening because the maven downloaded all the versions from the 1.0.0 not just the last one.
If I would use LATEST then just the 1.0.0-2 would be downloaded, but it's not what I want. Basically I would like to download just the latest from the 1.0.0.
How could I do this ?
Thank you for the answers!
(Maven version: 3.5.0)
First don't use versions ranges cause they make your build non reproducible.. If you like to update things like that you can use versions-maven-plugin to update the dependency. Apart from that what is the difference between 1.0.0-1 and 1.0.0-2..From your explanations i would assume you should change your versions schema cause the second one is not compatible with the first one so I would say 2.0.0 instead of 1.0.0-2..or is see it as a bug fix than 1.0.1...(following semver). Another point LATEST is marked deprecated for a long time and will produce a WARNING in the next Maven versions..
Coming to you explanations: I have my doubts that all artifacts are being downloaded...If you take a look at the logging output I assume there are some line saying ...maven-metadata.xml will be downloaded...
First part of the answer...

Why did a specific jar file get included?

I have a project that uses gradle and mavenCentral() (plus mavenLocal()). It has enough dependencies that I can't go through them one by one.
Given the name of a .jar file in build/install/x/lib, how do I find out the chain of transitive dependencies that caused it to be included?
update: I discovered gradle dependencies. The output shows:
org.apache.commons:commons-jexl:2.1.1
\---- commons-logging:commons-logging:1.1.1 -> 1.1.3
What does this mean? 1.1.1 is the version I expect, and 1.1.3 is the version I seem to actually end up using. Looking at the pom for commons-jexl it looks like it does indeed list logging:1.1.1 as a requirement. What's going on? Is there a way for me to tell it to avoid certain versions, or force it to use the version it was set to?
The problem in my case is that it's including a -SNAPSHOT version and I'd rather it didn't. In fact I probably want it to just use the version numbers I'm asking for instead of the most recent it can find.
Dependencies of gradle-managed project have their own dependencies (they're called transitive). It may happen (and happens quite often) that two different dependencies has the same (group and module) dependency but in the different version). This is the case with commons-logging:commons-logging. In this case there are two transitive dependencies one versioned with 1.1.1 and the second one with 1.1.3. If both of the libraries will be included in the final artifact it may result in a conflict and exception. To prevent such situation gradle tries to resolve mentioned version resolution problems by picking (by default) the latest version. It's indicated with the right arrow -> see here. You can exclude transitive dependencies from a particular dependency. This chapter of manual might be useful.

How does gradle evaluate dynamic dependencies?

The Gradle documentation is very sparse on how dynamic dependencies are resolved.
There are two styles of dynamic dependency declaration: lib:20.+ and lib:20.0+.
Are they equivalent?
Do 20.1 , 21 and 20.0.1 match these declarations?
Typically, I want to get fixes (x.y versions with x fixed) automatically and manually update to the next major version which can include breaking changes.
I have finally found an answer, in the Ivy documentation of all places :
Revision Matches
1.0.+ all revisions starting with '1.0.', like 1.0.1, 1.0.5, 1.0.a
1.1+ all revisions starting with '1.1', like 1.1, 1.1.5, but also 1.10, 1.11
source : http://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html

How to use maven version plugin in branch

I use maven version range for the dependencies in my parent pom.It works fine when I do a build on snapshot or a release.
But how should I need to proceed when I want to use the specific version of dependencies in a branch ?
For example: when I use version range such as (1.2.0,) it will always fetch the latest jar from the nexus repository. The latest would be like 1.2.5 as of when I do a release, since the dependencies are getting changed over and over.Now the latest version of my dependencies is 1.2.8-SNAPSHOT
In branch when I want 1.2.5 version for my dependencies, it is always looking for the latest one which is 1.2.5+
How to resolve this, while searching for similar questions I found that it could be resolved using maven-version-plugin. That requires a changes in the pom to add the plugin. But is there a solution without changing the pom and getting exact version for a dependency?
Any suggestions?
There is no solution without changing the pom at this point, if I understand the scenario correctly: In the release of a prior version of your product, the version of one (or more) of its dependencies was not fixated to the version available at the time. Now, in support of that previous release, the build has a different result than at the time of release.
There is no suggestion except to change the branch's pom to use the 'back' version available at the time of the release. Consider it a short term fix to a bug in the release process.

Resources