dependency spring-boot-starter-test not inherited in multiple module maven project - spring

In my multi-module maven project, all modules have a dependency of my own "common" module, eg, module "A" have this dependency "common". And the "common" module has a spring-boot-starter-test dependency. However, when I write unit test in this "A" module, it shows that the test dependency not imported. And then I check the dependencies and found that the spring-boot-starter-test is not imported. I want to ask why? In my sense, module "A" ref "common", "common" ref spring-boot-starter-test , so the module "A" should ref spring-boot-starter-test, but the fact is not that. By the way, in spite of this spring-boot-starter-test other dependencies works well via the hirachy. Does anyone know why it is? Thank you in advance.

Most likely in the module "A" dependecy spring-boot-starter-test has scope test. Dependecies with such scope is not transitive. See Dependency Scope section https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html.
The best solution is dependency management. See Dependency Management
Briefly, you need to create parrent module and declare dependency managment sectoin:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
Then inherit your modules from parent and just declare dependency without version and scope
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>A</artifactId>
</dependency>
</dependencies>

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..

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.

Maven test dependencies: how to get dependencies from sibling project into test scope of dependent project

I have a multi-module maven project with the structure
main/
core/
interface/
where interface has a dependency on the artifact produced by core.
interface compiles, packages, and installs properly. However, when running tests in interface they fail due to not resolving dependencies found in core.
interface does not depend on the test classes themselves in core, simply compile scope maven dependencies defined in the core pom.xml file.
I did one painful attempt whereby I copied every single compile dependency declaration in core that was needed into the interface pom.xml and gave them all
<scope>test</scope>
. This helped with the tests but broke the install.
What is the best way to fix the dependency resolution of these tests in interface?
Here is an example of compile scope dependencies that are not resolved when running interface maven test goal.
core/pom.xml excerpt:
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>${jsf-version}</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>${jsf-version}</version>
</dependency>
interface/pom.xml excerpt:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

Dependeny Management using POM import

I am creating a project 'test-jar' in my local and i am using pom file which I don't have write access as Parent of 'test-jar' project. The parent project has already defined depedencyManagement with old versions.
As I have to update dependency versions in my project and planning to override parent's dependency Management. So, I have created another POM file with my own dependency Management and imported into 'test-jar' project.
My Project :
<project>
<artifactid>test-jar</artifactid>
<parent>
<artifactId> test-parent </artifactId>
</parent>
<dependencies>
<dependency>
<artifactId>jar/artifactId>
</dependency>
<dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>custom-pom</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
</project>
My Parent Project:
<project>
<artifactid>test-parent</artifactid>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>jar/artifactId>
<version>1.0</version>
</dependency>
</dependencyManagement>
</project>
My Custom POM for updated dependencyManagement:
<project>
<artifactid>custom-pom</artifactid>
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>jar</artifactId>
<version>3.0</version>
</dependency>
</dependencyManagement>
</project>
The problem is, I am always getting dependency version from parent pom, though i have imported new dependency management in project.
I am using Maven 2.2.1 version here.
Is there any solution how to overwrite Dependency Management from Parent POM ?
Based on the documentation:
This scope is only used on a dependency of type pom in the
section. It indicates that the specified POM
should be replaced with the dependencies in that POM's
section. Since they are replaced, dependencies
with a scope of import do not actually participate in limiting the
transitivity of a dependency.
Apart from your problem you can simply use differerent version which are different of the onses defined in the parent pom's dependencyManagement. Furthermore you could create a separate pom wich defines the dependencies with new version (dependencyManagement) and inherits from the given parent.

Resources