Does Maven need to explicitly specify the dependency that Spring/Hibernate dependented? - spring

I'm new to Maven, I try to use Maven with Spring, Hibernate in my project. After go though the Spring and Hibernate reference, I found that "there is no need to explicitly specify the dependent liberaries in POM.xml file for such Apache commons liberaries".
My questions is that : If my other parts of project refer to Apache commons liberary, such as commons-io, SHOULD I explicit specify this dependency in POM.xml file?

You should define those dependencies in Maven which your project is using. For example, even though some library depends on commons-io but if your code needs this then you should directly define commons-io in your pom.xml
You should not worry about the dependencies of the libraries you have defined in your pom.xml. Maven will do that for you.

Maven is used to avoid the issue of having to run down JAR files that are dependent on other JAR files. Of course you do not HAVE to use maven to do this, but you should. Maven will automatically download the dependent JAR files of the JAR file you require. THe hibernate-entity manager JAR file, for example, has over 100 dependencies and maven does the work for you.
Anyway,even if you do add the commons-io file to the build path/classpath of the maven project,and then update the project configuration, maven will kick it out.

You can provide a lib name on a site like mvnrepository.com to see what it depends on (e.g. take a look at a section called "This artifact depends on ..." in case of spring-webmvc library). Those dependencies (which your artifact depends on) are called transitive dependencies. You don't have to specify these in your pom.xml as maven will resolve them for you.

For the sake of readability you should only state those dependencies in your module that you rely on directly. You want JUnit to test your software, only declare JUnit; you need hibernate to use ORM, declare hibernate, and so on. Leave the rest to Maven.
And most of the time you should state what you intend to use in the very module you want to use it in. So if you want to use a dependency in more than one module, consider moving it into a dependencyManagement block in a parent pom and referencing it from there in the module you want it in.
parent pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
child pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
This guarantees you version-stability and still allows you to find out what a module uses by only looking in it's pom (and not all over the place).

Related

How does maven resolve the dependencies of the main dependencies on which our application is build?

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]

Maven not importing External Library into project after adding to .pom file in Intellij

I'm having trouble correctly importing a library into a project that I'm running. I have added the library as a dependency in the .pom, refreshed the pom, run mvn clean install, and I have set auto-import up so that the project gets updated correctly, but the project does not get added as an External Library, and I can't use it in my project. I get no errors. What am I doing wrong?
Here is the relevant part of my pom
..properties
<crowd.version>2.5.0</crowd.version>
.. end properties
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.atlassian.crowd</groupId>
<artifactId>crowd-integration-springsecurity</artifactId>
<version>${crowd.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
Here is the question I was following to debug my error:
Import Maven dependencies in IntelliJ IDEA
I think you missed the point of dependency management; read more in official docs. This is a feature that you can centralize common dependency information that is then shared been different projects. All by itself, this definioition will not import the dependency.
What you probably want is just a plain dependency: drop the dependencyManagement tags, and move you dependency into the correct block in the pom.

Adding a dependency existing internally as a dependency

My project is a fairly large project consisting of many maven modules (but not microservices). I was trying to do Moving from spring to spring-bom on WAS but seems lot of clashes in versions. So for example one of my modules is using commons-collectionsversion 2.6.0 and my current project is using 3.2.2. I want the same jar to be used across. Since its more of a migration project I cannot do changes in container or repository changes at this time. I should only make sure that all the version are compatible with each other. My plan :
I want to include a dependency which is with in some other dependency
into the current pom as a dependency.
Also I want other jars in this pom (which exists as a dependency) to included the dependency
Is there anyway to do it?
I didn't completely understand your question, but the can help you to define a cross-module dependency version, as long as you place it in the parent-pom file.
<dependencyManagement>
<dependency>
<groupId>com.group</groupId>
<artifactId>project-1</artifactId>
<version>1.0.0</version>
</dependency>
</dependencyManagement>
and then define the dependency in the relevant module without providing it a version (it will be inherited from the parent-pom's <dependencyManagment> tag:
<dependencies>
<dependency>
<groupId>com.group</groupId>
<artifactId>project-1</artifactId>
</dependency>
</dependencies>

Maven: Include POM with used dependencies in assembly

We deliver our package with many external dependencies to customers. Now customers can use you libraries to develop stuff on top. For those who are also using Maven we would like to include a pom.xml file in the assembly which contains all dependencies, so they can simply use it in their Maven build:
It should contain all dependencies used by us as follows:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math</artifactId>
<version>2.1</version>
<scope>compile</scope>
</dependency>
Is there a way to achieve that in Maven?
The pom.xml for your jar/war is by default placed inside your jar/war in the location META-INF\maven\<groupId>\<artifacdId>
You have two choices:
The first one which is the most common and preferred way is relying on Maven's transitive dependency resolution.
Have a POM (assume called foo-api:1.0) in your project that declares the dependency (e.g. A:1.0:jar, B:1.0:jar).
Developer's own project (bar:2.0) should then simply depends on foo-api:1.0. Maven will simply include A:1.0:jar and B:1.0:jar as dependency of bar:2.0, through the transitive dependency resolution.
Another way is similar to the above approach, but use foo-api:1.0 as parent POM of bar:2.0.
Either way should work but which one is suitable depends on your design.

Can security JARS be loaded with Maven?

We have some unit tests that will fail unless you have two jars, local_policy.jar, and US_export_policy.jar in your $JAVA_HOME/jre/lib/security folder. I'm supposed to see if we can just put them in a project folder, then tell Maven to use them when it does a build("mvn install"). Maybe with something like the dependency tag? Yes, I know everyone should just install these in their $JAVA_HOME, but this is the task I've been asked to look into.
You are speaking about Maven dependency scope. Documentation here. You can say to Maven use some libraries just for testing using "test" scope.
You can add them as Maven systemPath dependencies.
systemPath
is used only if the the dependency scope is system. Otherwise, the build will fail if this element is set. The path must be absolute, so it is recommended to use a property to specify the machine-specific path (more on properties below), such as ${java.home}/lib. Since it is assumed that system scope dependencies are installed a priori, Maven will not check the repositories for the project, but instead checks to ensure that the file exists. If not, Maven will fail the build and suggest that you download and install it manually.
<dependencies>
<dependency>
<!-- The groupId can be anything. Use your own groupId for example -->
<groupId>anything</groupId>
<artifactId>local_policy</artifactId>
<!-- The version can be anything. Use the version of Java for example -->
<version>7.0</version>
<systemPath>${java.home}/lib/security/local_policy.jar</systemPath>
<scope>system</scope>
</dependency>
<dependency>
<!-- The groupId can be anything. Use your own groupId for example -->
<groupId>anything</groupId>
<artifactId>US_export_policy</artifactId>
<!-- The version can be anything. Use the version of Java for example -->
<version>7.0</version>
<systemPath>${java.home}/lib/security/US_export_policy.jar</systemPath>
<scope>system</scope>
</dependency>
</dependencies>

Resources