why version dependency needs to be specified? - maven

I have pom.xml like,
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>1.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
I am unable to understand why am I required to specify version on cdi-api under dependencies when it is already defined in microprofile (inside dependencymanagement).

This pom isn't a standard bom that would define version of the dependencies but must be used like a standard dependency: https://github.com/eclipse/microprofile-bom
This style of BOM does not go in a
dependencyManagement section, using import
scope, and you cannot add dependencies declared in the BOM without
version elements as is typically done with that style of BOM.
You actually need to depend on that pom:
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<type>pom</type>
</dependency>
Don't forget to add the type pom and either specify the version or reference this version in your dependency management with type pom if you want everything to work. glytching forgot the type pom, that's why this doesn't work.

The org.eclipse.microprofile:microprofile artifact declares a dependency on javax.enterprise:cdi-api so if you declare org.eclipse.microprofile:microprofile as a dependency in your POM then javax.enterprise:cdi-api will be provided transitively.
In the example in your question you declared org.eclipse.microprofile:microprofile in the <dependencyManagement> section, this section consolidates management of the version, scope, and exclusions for each dependency but in order to use that dependency in your project you must include it in the <dependency> section.
So, if you add this to your <dependency> section ...
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
</dependency>
... then org.eclipse.microprofile:microprofile will be included in your project and hence javax.enterprise:cdi-api will be included transitively and you won't have to declare it explicitly.

Related

How to stop Maven from downloading all historical versions of aws-java-sdk?

I am using Maven to download aws-java-sdk dependency for version 1.11.23, though in Maven repository I find all historical versions till most recent ones; i.e. aws-java-sdk-sqs downloaded versions (1.9.0 to 1.11.642) any idea why is that and how can I limit to only the version specified for aws-java-sdk artifact?
This "dependency loop" is a problem with some older versions of aws-lambda-java-events, which is probably a dependency of your dependency.
Try updating or your dependencies to the latest, or overriding aws-lambda-java-events to at least 2.2.7:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.2.7</version>
</dependency>
For me, After specifying the BOM of AWS SDK in the dependencyManagement section & the version I would like to use, The historical downloads were stopped. Below are my dependencies.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.10.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
I created a project (with Maven 3.5.4) with just:
<project ... >
....
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.23</version>
</dependency>
</dependencies>
</project>
All of ~/.m2/repository/com/amazonaws/* (as declared in aws-java-sdks POM) contain just the sub-directory /1.11.23.
UPDATE
To exclude dependencies of your dependencies see Introduction to the Dependency Mechanism, Transitive Dependencies:
Excluded dependencies - If project X depends on project Y, and project Y depends on project Z, the owner of project X can explicitly exclude project Z as a dependency, using the "exclusion" element.

Can't add dependency to pom.xml file

I am following a Springboot tutorial on a website I found. The site tells us to add various dependencies to our pom.xml file. I added the web and thymeleaf dependencies through the Spring Initializr. Hwoever, I realized that I forgot to add the security dependency. When I try to edit my code and add the security dependency by typing:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
You should either inherit your project from spring-boot-starter-parent:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
</parent>
The parent project provides the following features:
Java 1.8 as the default compiler level.
UTF-8 source encoding.
A Dependency Management section, inherited from the spring-boot-dependencies pom, that manages the versions of common dependencies. This dependency management lets you omit <version> tags for those dependencies when used in your own pom.
An execution of the repackage goal with a repackage execution id.
Sensible resource filtering.
Sensible plugin configuration (exec plugin, Git commit ID, and shade).
Sensible resource filtering for application.properties and application.yml including profile-specific files (for example, application-dev.properties and application-dev.yml)
Or use the spring-boot-dependencies BOM:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Using the BOM is the way to go when you would not like to inherit from the spring-boot-starter-parent POM. You may have your own corporate standard parent that you need to use or you may prefer to explicitly declare all your Maven configuration. You would still keep the benefit of the dependency management, but not the plugin management.
Both solutions will allow you to omit versions of Spring dependencies.

How to remove spring boot dependency using dependencyManagement?

In my pom file i have the following:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I use this because the project already have a parent pom.
I want to remove some of its dependencies such as:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
How do I do this?
spring-boot-dependencies does not add any dependency. It mostly consists out of a giant <dependencyManagement> block containing managed versions for several libraries. This allows you to use versions of libraries that are known to work properly with the given version of Spring boot.
That means that you no longer have to add the <version> to each dependency you define.
It also means that if you have a dependency upon elasticsearch, it certainly doesn't come from spring-boot-dependencies.
If your goal is to override one of the versions, you can, by manually adding <version> to your dependency.
Otherwise, you can usually exclude a dependency by using <exclusions>:
<dependency>
<groupId>com.xyz</groupId>
<artifactId>artifact-abc</artifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>

How to declare in a super POM the exclusions of an artifact when the artifact version is imported from a BOM

I am using a BOM to declare the version of common artifacts across my projects.
I am importing the BOM in the dependencyManagement section of a super POM in a project with several submodules, like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>mybom</artifactId>
<version>bomversion</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencies>
</dependencyManagement>
The objective is that children of this super POM will not have to declare the version of the modules they need. This works fine.
However, I also would like to being able to specify in my super pom that certain dependencies should be imported with exclusions, like:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>artefactgroup</groupId>
<artifactId>myartifact</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
</dependencyManagement>
The problem with this is that somehow the version is not recognized from the imported BOM in myartifact. Is that the expected behavior?
Which is the best way to declare exclusions in my super POM so the version can is taken from the BOM?
If I do not declare the exclusion in the super POM but in each child that requires myartifact it works, but the same exclusion declarations are spreaded everywhere in my project, which is far from being a good idea.

How to exclude transitive dependencies of spring-boot-dependencies from maven import scope

I have the following in my Spring Boot application pom as per the documentation:
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I need to use use dependencyManagement and <scope>import</scope> because I need to use a standard corporate base pom.
However, it doesn't seem possible to exclude transitive dependencies of spring-boot-dependencies. In my particular case, Spring Boot 1.2.1.RELEASE is bringing in a version of Jetty that is too new with respect to some of my other <dependencies>. I tried using an <exclusion> of the form:
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
<!-- Doesn't work -->
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
using Maven 3.2.1's wildcard support, but it doesn't seem to take effect.
Is there a solution to this problem other than explicitly overriding all the Jetty dependencies? There are many Jetty libraries and that approach would be quite brittle. Furthermore, it appears I would need to do the same with Jetty's transitive dependencies as well.
According to the Spring Boot Maven Plugin 2.3.1.RELEASE documentation, to override individual dependencies, you need to add entries in the dependencyManagement section of your project before the spring-boot-dependencies entry.
<dependencyManagement>
<dependencies>
<!-- Your jetty version dependency -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>*</artifactId>
<version>${jetty.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Looks like this isn't possible with Maven import scope:
The import scope can be used to include dependency management
information from a remote POM into the current project. One of the
limitations of this is that it does not allow additional excludes to
be defined for a multi module project.
Likewise, there is a confirmation from the Spring Boot documentation:
If you have added spring-boot-dependencies in your own
dependencyManagement section with <scope>import</scope> you have to
redefine the artifact yourself [...].

Resources