Why is spring-boot-dependencies in dependencyManagement? - maven

The Spring documentation Using Spring Boot without the parent POM shows that the dependency on spring-boot-dependencies is added to the dependencyManagement section. Is this really correct?
spring-boot-dependencies specifies version properties for all the dependencies. However, these properties are not available in the POM that uses spring-boot-dependencies. Presumably, this is because spring-boot-dependencies is in dependencyManagement.
spring-boot-dependencies only includes dependencyManagement and pluginManagement. So it seems possible to include spring-boot-dependencies as a dependency (not dependencyManagement) without adding unnecessary dependencies.
So why is spring-boot-dependencies to be included as dependencyManagement?

So why is spring-boot-dependencies to be included as dependencyManagement?
Let's say you have a project named projectA and you add the spring-boot-dependencies to the dependencyManagement section in your pom.xml.
<project>
<groupId>com.iovation.service</groupId>
<artifactId>projectA</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>pom</type>
<version>1.5.8.RELEASE</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
...
</project>
If you notice closely, you will find that all the Spring Boot dependencies declared under the dependencies section don't need to specify the version. It derives the version from the version of spring-boot-dependencies specified in the dependencyManagement section.
Advantages of Dependency Management
It centralizes dependency information by specifying the Spring Boot version at one place. It really helps during upgrade from one version to another.
Subsequent declaration of Spring Boot dependencies just mentions the library name without any version. Especially helpful in multi-module projects
It avoids mismatch of different versions of spring boot libraries in a project.
No Conflicts.

It's definitely correct. Please see Using Spring Boot without the parent POM!

First, let’s understand what dependency is. So when you are developing an application, you would probably need a number of libraries(normally jar files). It means that your application depends on these libraries. Hence the name dependency.
Now you need a way to assemble all these libraries and manage them in a centralized fashion. This also means that these libraries would be made available at compile time or runtime when needed. This is what dependency management does.
So the process of dependency management involves locating these dependencies and adding them to the classpath.
Maven is a popular dependency management tool which will centralize all dependencies information.

Related

Using dependencies of an artifact

I have a complex Spring project with tens of dependencies and modules. I notice that some of them might be replaced by spring-boot-starters.
However, when I'm replacing some dependencies with starters in main, parent pom, I'm getting errors in children modules.
Here's an example:
PARENT POM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
MODULE POM
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
According to maven repository spring-boot-starter-activemq depends on, among others, spring-boot-starter and spring-jms.
Should these dependencies be available for modules?
Is there a way to use dependencies like that? I would make pom files shorter.
Or maybe is it a bad idea to do it like that and I should define all dependencies I will use in dependencyManagement?
In a POM, you should have all the dependencies that you directly use in your code. Do not rely on transitive resolution for things you actively use.
Your construction does not work because you did not manage the spring-jsm and spring-boot-starter in your dependencyManagement. Being a dependency of the managed dependency does not help.

Dependencies vs DependenciesManagement?

I have gone through differences between dependencymanagement and dependencies in maven but i am still unclear when to use
just dependencies tag in parent pom and when to use dependenciesManagement tag ?
My understanding is when my all child modules need to use same dependency version then we should declare the Dependencies under Dependencies tag(without dependencyManagement tag)
But on other hand if some of the child project need to use different version then we should declare the Dependencies under Dependencies tag(which will be under dependencyManagement tag). then Child modules can refer them with overridden version
Is that correct ?
Declaring a <dependency> within <dependencyManagement> does not set the specified artifact as dependency for any project – parent or childs. It just states: If you want to use this as dependency then you can use it with these settings (version, scope, ...) without having to specify the settings again, and again, and ... You can, however, override a "management" setting in a "real" <dependency> anytime.
See also POM Reference, Dependency Management.
There are two options for a parent POM regarding your second paragraph:
As you describe correctly:
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
I'd use this for consistency:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>g-id</groupId>
<artifactId>a-id</artifactId>
</dependency>
</dependencies>
Your third paragraph is correct..

maven spring library correct dependency

Let's say I am creating a new project, maven based, and I want to use spring 4.2.3.RELEASE.
I also want to use spring-test and spring security and X, Y and Z.
How can I know for sure what exact versions to add in maven to avoid conflicts?
Thanks
later edit:
can this help me?
Maven "Bill Of Materials" Dependency
It is possible to accidentally mix different versions of Spring JARs when using Maven. For example, you may find that a third-party library, or another Spring project, pulls in a transitive dependency to an older release. If you forget to explicitly declare a direct dependency yourself, all sorts of unexpected issues can arise.
To overcome such problems Maven supports the concept of a "bill of materials" (BOM) dependency. You can import the spring-framework-bom in your dependencyManagement section to ensure that all spring dependencies (both direct and transitive) are at the same version.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.2.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
An added benefit of using the BOM is that you no longer need to specify the <version> attribute when depending on Spring Framework artifacts:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
You are right, the BOM is one of the most powerfull ways to fight (even maven based) dependency hell.

Dependencies in Dependency Management vs Dependencies in Maven versions plugin

When I use Maven versions:display-dependency-updates to check dependencies updates, I get two sections of result.
1st:
The following dependencies in Dependency Management have newer
versions:
2nd:
The following dependencies in Dependencies have newer versions:
What's the difference between these two?
The Dependency section of the POM defines the artifacts (jars, zip etc) upon which your project depends. i.e. the artifacts that it requires to compile, run etc.
The Dependency Management section of the POM is used to manage dependency information.
So for example, in the following pom the JUnit dependency is defined completely in the dependencyManagement section of the POM with version=4.11 and scope = test.
In the dependency section you simply need to define the JUnit dependency using the groupId and artifactId and maven automatically picks up the version and scope from the dependencyManagement section.
<?xml version="1.0" encoding="utf-8"?>
<project>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependencies>
</project>
Usually you would define the dependencyManagement section in a parent POM, where you define the version and scope for all dependencies. Then in the child module's you simply need to define the dependencies using the groupId and artifactId. This allows you to centrally manage versions and means you only have to update them in one place.
All of this is far better explained in the maven documentation:
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
The Versions Maven Plugin is simply listing the versions found in each of these sections, as it is possible in the dependencies section to override the version that was defined in the dependencyManagement section.

How to use jars from Wildfly correctly in Maven?

I'm working on a project to deploy to Wildfly, and I'm using Maven to build it. This is a complex project with multiple war/jar/ear files, so there's a parent pom.xml with the following in it:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>jboss-javaee-7.0-with-all</artifactId>
<version>8.1.0.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
...
Unfortunately, the above BOM does not include various jar files that I know are in the default Wildfly 8.1.0.Final distribution. In particular, the cause of this question is the cxf-api jar file. I know it resides at this location in Wildfly:
wildfly-8.1.0.Final/modules/system/layers/base/org/apache/cxf/main/cxf-api-2.7.11.jar
but it is not being managed by the BOM recommended for Wildfly.
How do I correctly add cxf-api, and similar jar files, to the project's pom.xml, preferably without having to specify each one individually? Sure, I could do something like this:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>2.7.11</version>
<scope>provided</scope>
</dependency>
but I'd really rather not have to do this for each and every jar file that is already a part of Wildfly.
Isn't there a BOM that I can import?
WildFly BOMs (aka JBoss Bill of Materials in its original version) is a set of dependencies used to enhance deployment of dependant projects and automate in some way their tests. It does not unfortunately includes dependencies used in WildFly core i.e. the Application Server.
The pom.xml (project descriptor) that you really need to import just the way you did for your BOMs pom file is the WildFly parent pom. So just import it into your own project pom and you will have your dependecies transitevelly resolved:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-parent</artifactId>
<version>8.1.0.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Checkout the Apache CXF version used in the target WildFly version and just pick up the stable tags that match your needs.

Resources