Using dependencies of an artifact - spring

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.

Related

Why is spring-boot-dependencies in dependencyManagement?

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.

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.

Excluding some 3rd party jar in ear using maven

I am building an ear using maven <packaging>ear</packaging> tag.
One of the declared dependencies is adding it's transitive dependency to the generated ear. Is there any way to exclude this in the generated ear?
That is, my EAR pom has a dependency on module_A, this somewhere along the tree has a dependency on module_X which is getting packaged in the generated ear.
Is there any way not to include this(module_X) in the ear?
Directly adding an excludes tag for module_X in my pom did not work.
Everything is possible with maven. You just have to simly add a tag exclusions in the pom of your ear, something like that :
<dependency>
<groupId>my.group</groupId>
<artifactId>module_A</artifactId>
<exclusions>
<exclusion>
<groupId>my.group</groupId>
<artifactId>module_X</artifactId>
</exclusion>
</exclusions>
</dependency>
If the dependency is scoped as compile in the parent POM and you need it to be provided within your EAR, you can use dependency management within the child POM where you need to change its scope:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.group</groupId>
<artifactId>transitive-dependency</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>

why don't use scope maven dependency Management?

if i define this dependency at parent's pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework<groupId>
<artifactId>spring-core<artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
and in one of the childss:
<project>
<dependencies>
<dependency> // note: no version declared
<groupId>org.springframework<groupId>
<artifactId>spring-core<artifactId>
</dependency>
so, the scope? is always compile, or can i specify?
compile is the default scope for a dependency (pom reference). You can specify scope also and it will be inherited

Resources