How can I in an very easy way retrieve all direct and transitive dependencies for a given Maven POM in my own Java program?
I aware of the existing questions on Stackoverflow, especially the one using Ivy to resolve the dependencies. I am looking for a solution using Maven, which is able also to resolve the transitive dependencies.
If you need this during a Maven build, you can easily access it in a Maven plugin using project.getDependencies().
If you have a standalone Java program, you can use Maven resolver or the older Aether libraries to do the resolution.
I was now able to solve the problem by using JBoss Shrinkwrap.
Here is a code snipped similar to the one I now use in my tools:
MavenStrategyStage resolve =
Maven.configureResolver()
// do not consult Maven Central or any other repository
.workOffline()
// import the configuration of the given settings.xml
.fromFile(homeDir + "/jqa-release-environment/maven-settings.xml")
// load the POM you would like to analyse
.loadPomFromFile(pomFile)
.importCompileAndRuntimeDependencies()
.importRuntimeAndTestDependencies()
.resolve();
MavenWorkingSession mavenWorkingSession =
((MavenWorkingSessionContainer) resolve).getMavenWorkingSession();
List<MavenDependency> dependencies = new ArrayList<>();
dependencies.addAll(mavenWorkingSession.getDependenciesForResolution());
dependencies.addAll(mavenWorkingSession.getDependencyManagement());
To be able to use Shrinkwrap, I added the following dependencies to my POM.
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<type>pom</type>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-api-maven</artifactId>
<version>3.1.4</version>
</dependency>
Related
How to use the Liberty's distributedmap feature in a Java application?
Where I can find the required Maven dependencies (com.ibm.websphere.cache..)?
The Maven dependencies for WebSphere features like the DistributedMap are defined in the https://github.com/WASdev/ci.maven.tools repository and they are published on Maven central.
The following dependency loads all APIs:
<dependency>
<groupId>net.wasdev.maven.tools.targets</groupId>
<artifactId>liberty-apis</artifactId>
<version>${liberty.dependency.version}</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
The Maven coordinates for the distributedMap API would be:
<dependency>
<groupId>com.ibm.websphere.appserver.api</groupId>
<artifactId>com.ibm.websphere.appserver.api.distributedMap</artifactId>
<version>2.0.68</version>
</dependency>
Each release of Liberty will have a different version, but that is from 22.0.0.9 the latest version as of this response. I found this by using search.maven.org and searching for distributedMap. This should work for other features APIs as well.
I have dependency in pom with groovy-all
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.7</version>
<type>pom</type>
</dependency>
But if I check libs inside, I see 2.5.13 versions. How can I change all of this libs to 3.0.7? Of course I can add separately, but maybe is another option?
The versions are managed in the <dependencyManagement> section of the POM, either directly or by using a BOM (scope import).
If you want to update them, you need to look there.
You are importing Groovy 2.5.13 elsewhere likely as a transitive dependency and maven is deciding to use 2.5.13 instead of 3.0.7.
Look at the groovy 3.0.7 pom:
https://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/3.0.7/groovy-all-3.0.7.pom
It has no reference to 2.5.13.
Why to include
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.9.1</version>
</dependency>
to the maven project if we still need to download the driver's binary?
What is the advantage?
What will happen if we change the version in dependency, but not download the new binary?
The Selenium Maven Artifacts can be found in the Central Maven Repository. Now to start using any of the implementations in your Maven project, you just need to add the required dependency within your pom.xml (current release being Selenium v3.141.59):
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
The diagram below shows the dependencies between the different Selenium Maven Artifacts as well as the most important classes/interfaces in those artifacts:
If you know that you will only use a certain WebDriver implementation, e.g. the FirefoxDriver, you don't need to depend on the selenium-java artifact (which has a lot of transitive dependencies). Instead you can just add the selenium-chrome-driver dependency on the artifact you need.
I am trying to understand maven a little more. How is maven able to download the dependencies of the main dependency of the application? For example assuming my application has main dependency like this:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.0</version>
<scope>provided</scope>
</dependency>
Now, when maven downloads this jar , it downloads the dependencies for this jar as well. For example, see the screen shot below:
As can be seen, maven has not only downloaded the hadoop-hdfs-2.7.0.jar but also all it dependencies.
Now, my questions is how maven knows what are the dependencies for the "top-level" dependency, that is in this case the "top-level" dependency is hadoop-hdfs, so what all jars it has to download for this?
I see this as well in the .m2/respository for hadoop-hdfs:
I opened the .pom file, the contents are (partly):
<project>
....
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.0</version>
<description>Apache Hadoop HDFS</description>
<name>Apache Hadoop HDFS</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<scope>provided</scope>
</dependency>
<dependencies>
...
</project>
What is this hadoop-hdfs-2.7.0.pom ? Does this file give information to maven what are the dependencies to be downloaded for hadoop-hdfs-2.7.0.jar?
Can anyone help me clear these things?
First of all you are right, the hadoop-hdfs-2.7.0.pom tells Maven
about the libraries that hadoop depends upon. But, when using hadoop
as a dependency in your project, maven uses the below strategies to
finalize the list of dependencies in addition to using the
hadoop-hdfs-2.7.0.pom.
If a dependency is specified with groupid, artifactid and version in the current project under the dependencies tag, it takes the first
precedence. This is how hadoop-hdfs got added in your project.
Dependency Management takes the next precedence. When a dependency is specified only with group and artifact id's under dependencies tag
but at the same time, the dependency is defined under
dependencyManagement tag with version and transitively inside hadoops pom.xml also,
the one under the dependencyManagement tag will be given preference.
Dependency Mediation takes the last precedence. Dependencies are resolved using dependency mediation. Meaning, in your case the
dependencies mentioned inside hadoop-hdfs-2.7.0.pom are the transitive
dependencies (indirectly depends on these dependencies since your
dependency "hadoop-hdfs" requires it) of your project and this process continues
recursively until all child dependencies are resolved.
Note: There are other features such as excluding dependencies, marking
one optional and importing a list of dependencies. But they are used
sparsely. More information with examples can be found in the below URL
[https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management][1]
Problem is a bit stupid but I can't find any spring3.0-with-dependencies.jar. Is it assumed that I should find all necessary dependencies by myself?
May I use dependencies from spring 2.5 in this case? UPD: answer is no, I can't. So, where are the dependencies??
I guess they don't release them any more. You can have the dependencies automatically if you use maven or ivy. All you need is to define the dependencies in your pom.xml like this:
<pom>
...
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
</dependencies>
...
</pom>
Maven will bring all the dependencies transitively.
If you are using Maven, you can get Spring 3.0 jars (and their transitive dependencies) from the central repository. Simply add this to your pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
For more details, more artifacts, check out Obtaining Spring 3 Artifacts with Maven (and please, don't use EBR if you don't need it or I guarantee the nightmare).
Usually the readme.txt file has the dependencies listed for each module. With that you can usually get them easiest from the maven repository... or better yet, with maven (http://maven.apache.org).