how to set default version in mvn pom - maven

H, I have a multi project that have inner dependencies and I use ${project.version} parameter to the dependencies. I want to set a default version that if the version of the specific artifact doesn't extrinsic he will use the default version.

This is not possible. You cannot have dynamic versions. The only thing that comes close are version ranges (like [1.0, 2.0)), but they fell out of fashion.
I still cannot really imagine a case in which this would be useful. First of all, if you have a list of 10 repositories you can just look up if a version exists or not. Why should it exist "sometimes"?
Secondly, if you have a "default version", why not just always use that? What do you gain from having another possible version?

Related

How to compile against lower bound in Maven dependency version range

Is there a way, in Maven, to declare a dependency version range and have it resolve against the lower bound for the compile phase of the build?
eg. I declare a dependency using version range [1.2.0,1.999.999]. I would like for the compile phase to use version 1.2.0, specifically, but for the deployed POM to still show my compatible version range as [1.2.0,1.999.999].
My project is a library. For a non-library project I would just pin a specific version.
I see your point, but I am not sure this is the right idea.
First of all, version ranges are not very popular nowadays. People tend to avoid them because the build is not reproducible. AFAIK, they are not really deprecated, though.
Using version ranges to show compatibility is unexpected. Maybe a comment in the POM would be better.

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...

Force Maven to use latest dependency among the ones present in dependency tree

I understand Maven's behavior whenever it finds more than one version of the same dependency is to choose the one closer to the dependency root. If more than one are same as close, then it will choose the first one it finds.
Is there a way to change this behavior and make it simply pick the highest version?
The versions plugin can do some of the work for you, by rewriting your POM, but I highly recommend avoiding using it. Explicitly managing dependencies as gogstad and Michael stated is the recommended path.
Add a dependency management section and pick the version you actually want to use. You should always be setting versions so you're getting repeatable builds.
No, it's not possible to change the maven dependency mechanism to anything other than nearest definition.
If you experience that maven chooses the wrong dependency, the only way to fix it is to explicitly depend on that dependency in your application (maven will of course not allow two different versions of the same dependency in the clasdpath at the same time). The dependency you define will be used in any transitive dependencies for the same artifact.

Version ranges in gradle

What are the possible ways of specifying version ranges in gradle dependencies? I saw some 1.+ notation but I have not found a document which really says what is possible and what is not. Furthermore, I do not know whether the Maven ranges can be used as well.
Can somebody give me a short overview so that I can understand the rules?
The book "Gradle Dependency Management" states on p. 12 and 13 that, in addition to the +-notation (2.1.+ means the range from 2.1.0 inclusive to 2.2.0 exclusive) you can use the Ivy notation for open and closed intervals of the form
[1.0,2.0]
[1.0,2.0[
or also
[1.0, )
for "all versions starting from 1.0".
Preferred alternative
Specify the version range using Ivy notation. Here are some examples copied from this web page:
[1.0, 2.0]: all versions >= 1.0 and <= 2.0
[1.0, 2.0[: all versions >= 1.0 and < 2.0
[1.0, ) : all versions >= 1.0 // avoid. Unbound is dangerous!
Troublesome alternative
Use '+' in the major, minor or patch number. This approach has at least two issues:
If you're building a lib and generating a pom file, the pom will be incompatible with maven, unless you apply some workaround to resolve the version and prevent the pom dependency to use '+' in the version element. See this Gradle github issue.
The meaning of '+' is prone to confusion. Well, maybe not, but ask around to see if all your peers know exactly the difference between 1.1.+ and 1.1+ in a gradle dependency.
Ideal alternative
Avoid dynamic dependencies (using '+' or version ranges) altogether. Instead, use a fixed version dependency and update the version often with good testing. Here's why:
In the old days, backwards compatibility was sacred. That's not true anymore. New versions often move/remove/rename classes and functions.
If your dependency is dynamic (especially with '+' or unbound range), the next build may pick a new version that is incompatible with your project. The incompatibility may be detected only at rutime.
Version X of your library as built today might be different from version X of your library built tomorrow if one its dependencies is dynamic and a new version is released overnight. This level of uncertainty is not desirable for libraries.

Named versions in Maven?

We are using mvn pom.xmls to specify interdependency between our various modules that make up the project.
The numeric version for every module is incremented by the build system automatically when the module is released.
However, in this case, this would necessitate notifying every team to update the version their module depends on to the version we just released.
Can Maven instead just work in a way that users of a library specify something like, "depend on the 'STABLE' version of this module", and then with every build it would figure out which actual version number that translates to?
Why don't you just depend on the major version, and release minor versions?
<version>[1.,)</version>
You can also use RELEASE
<version>RELEASE</version>
However I guess that's not supported in Maven 3.
See more discussion about the same topic from this thread.

Resources