I want to find all the higher versions available for each dependency and download them all of them. I tried to get the version by this command
versions:display-dependency-updates
But it is only displaying the latest version. Instead how should I find all higher versions using a java.
First of all, updating all the dependencies of a project just for having the latest version isn't the most recommended option. You may encounter unintended consequences such as, for example, changing the Java version with which the projects were compiled so you can't deploy your application on your server. My recommendation is that you always keep control of the dependencies you use in your projects and define a specific value appropriate to your needs. But if the supplier of the dependencies is a trustworthy organization and maintains compatibility between its versions, you can use the maven dependency syntax to get the latest. Dependency Version Ranges
Related
I want to use different selenium versions (3.141.59 and 4.1.0) for running my project in chrome and firefox browser and android,
Is it possible to use different version of selenium dependency in POM for different browsers in same JAVA project?, if so how it will code.
You can define, but only one will be picked at a time !
As per maven documentation
Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins
Read more about it here
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Ideally I'll suggest to you to use a stable version of selenium compatible with both browsers !
I've recently been introduced to the concept of a dependency version lock file when reading about package managers like NPM, Yarn, Paket, Cargo, etc. My understanding is that it is a file that lists all direct and transitive dependencies along with their exact version number so subsequent builds are guaranteed to use an equivalent set of dependencies. This seems to be a desirable feature since many package managers have or are adopting the concept.
My questions are then:
Why doesn't Maven or Gradle use a lock file? Or if they do, why haven't I seen it?
What are the pros and cons of allowing version ranges in a package manager's dependency resolution strategy vs only allowing exact versions?
Maven does not have a way of to achieve what you are asking for. Even if you set specific versions for your direct dependencies, which you should, your transitive dependencies can easily be unintentionally changed due to a seemingly unrelated change. For example, adding a dependency on a new library can give you an older version of an existing transitive dependency.
What you need is to have a dependencyManagement section that lists all your direct and transitive dependencies. You will still not be able to detect if a transitive dependency is removed or added which is a feature that, for example, NPM provides. The problem with missing that is that all your dependencies are no longer in the dependencyManagement section. To detect those changes you could use something like dependency-lock-maven-plugin which I have written. Using it will also make it less important to have everything in a dependencyManagement section since changes in transitive dependencies will be detected.
I would also recommend having https://maven.apache.org/enforcer/enforcer-rules/requireUpperBoundDeps.html in your build since Maven chooses the versions of the transitive dependencies that are closes in the tree and not, as you would expect, the highest version.
I have seen many runtime problems caused by developers accidentally changing transitive dependencies.
TL;DR: You do need something like a lock file in Maven, but it is not there due to historical ideological reasons.
I would not recommend using version ranges since they make your build not reproducible.
Neither does it behave as you would believe when it comes to transitive dependencies.
Dependency locking was a feature that achieved some maturity by Gradle 5.0:
https://docs.gradle.org/current/userguide/dependency_locking.html
Gradle's implementation was inspired by the Nebula plugin: https://github.com/nebula-plugins/gradle-dependency-lock-plugin
Version ranges do work well, when used as input to whatever updates your locking mechanism. So, for Gradle, you can actually just target specific dependencies that will look to resolve version ranges you've specified for:
gradle classes --update-locks org.apache.commons:commons-lang3,org.slf4j:slf4j-api
Or, you can just say "go update all my deps":
gradle dependencies --write-locks
Specifying resolution strategies is also worth reviewing, if you're looking into automation: https://docs.gradle.org/current/userguide/dependency_resolution.html
Both Maven, SBT and Gradle have what you're describing. It's called "using released (or fixed) versions". A released version looks like 1.2.3, as compared to a version range [1.2.3,), or a snapshot (1.2.3-SNAPSHOT).
If all your dependencies are using released versions, you will achieve what you're describing.
Version ranges are a valid form of versions as well, depending on your use case, but I would normally advise against them, unless they're used for parent POM-s, or just during active development. Version ranges can come handy when you'd like to not have to keep updating the fixed version of a third-party, or parent POM, if you're certain that the respective artifact can in no way break things for you (and, trust me, this does happen a lot with version ranges). Fixed versions should be used when you'd like to guarantee that the code will build and work against what you originally devised and tested it.
There is no need to have a feature such as "lock file", or anything like this, if your pom.xml strictly defines the versions of your dependencies.
If you read the documentation regarding dependency management, you will see that this is indeed so:
Maven
Gradle
SBT
Our project is like an adapter/facade interface for a huge amount of different other libraries. The dependencies are somehow overlapped, sometimes in conflict or sometimes even make project breaks in silence for wrong version of dependencies provide wrong behavior of same interface.
We are using Ivy and Ant to do basic dependencies management.
What's the best practice to manage dependencies and detect wrong behavior early on?
The important part of this question is about process, not tools.
If a project's dependencies are owned by other teams or third parties, that project must explicitly accept each new version of each new dependency. Allowing dependencies to upgrade themselves would allow them to break the depending project without warning, which is what it sounds like is happening.
Each dependency must release known versions, whether as binaries or tags in version control or whatever is appropriate to your stack. Each time a project wants to upgrade a dependency, it must test the result of the upgrade. (As usual comprehensive automated testing will be a big help.) If it fails (either because the dependency is just broken or because the dependency brings in an incompatible version of a transitive dependency), abandon the upgrade, report the problem to the owners of the dependencies, and try again after they've released a version which fixes the problem. If it succeeds, change the version of the dependency that the project uses in its build configuration.
Ideally a project will upgrade dependencies one at a time and fully test each upgrade separately. If it's necessary to upgrade more than one dependency all at once (perhaps because two dependencies both depend on a third dependency of which there can only be one version in the system) that's fine, although it's a bigger change and thus riskier. If your project has transitive dependencies like this, it will be worth the engineering effort to make them backward-compatible over as many versions as is reasonable.
Of course many tools support this process easily enough: just pin each dependency to a specific version.
This sounds to me like a generic problem so I'm wondering if there is a general recommended way to deal with these situations regardless of the build / dependency management tools used (Gradle in my case). I can imagine this issue arising regardless of the build tool, even in a small project where the few dependencies are handled manually and which is simply built with Java using the jar command.
My Java project uses Velocity 1.7 so it has the Velocity 1.7 JARs in its classpath.
However this project also uses ReportNG, which depends on Velocity 1.4 (it even has the entry Class-Path: velocity-dep-1.4.jar in its manifest, plus its downloaded zip contains velocity-dep-1.4.jar and its home page explicitly mentions that velocity-dep-1.4.jar must be in the classpath).
I'm wondering how to avoid having on my classpath the JARs for both Velocity versions, which is the likely cause of strange behavior I'm seeing and which in any case doesn't sound at all like a good idea.
I'm going to try to make ReportNG use Velocity 1.7 instead of 1.4 but it won't necessarily work and I'd like to avoid doing that if there is a clean way of dealing with these situations.
While you can add both JARs to the classpath, by default Java will use first JAR it finds containing a given class, which, depending how you construct your classpath can have undesirable effects on your system.
To avoid this situation Gradle (like Maven before it) resolve dependency conflicts at build time.
With Gradle, the default dependency resolution uses the newest dependency, which in your case means Velocity 1.7.
With Maven dependency resolution is achieved by using the closest dependency to your project, which in your case, as your project declares a dependency on Velocity 1.7, means it is that version that would be used.
With both approaches, whether your system (or rather ReportNG) will work with Velocity 1.7 is down to you to test.
Is there a common way of finding out which version of a Maven artifact is compiled against which Java version?
It always seems to take way too long to
Work out that it is a jvm version issue
Find out which jvm version the current aritfact uses
Track back through the versions of the artifact to find one that works
If there is not a common mechanism, do some artifacts adopt a naming convention?
There is a standard way of naming, using the classifier attribute of an artifact.
Building same project in Maven with different artifactid (based on JDK used)