Use transitive dependencies and exclusions with Maven - maven

I have this maven hierachy :
sim-java
ejb
web
log4j
...
ejb, web and log4j are modules of sim-java and each of these modules refer to sim-java by parent tag.
I would like to create a log4j module and include it as dependency in sim-java so log4j will be present as dependency in ejb and web modules.
Basically, my pom.xml inside sim-java contains this :
<dependencies>
<dependency>
<groupId>com.sim</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
(scope is provided as I have an ear module which will include com.sim:log4j in ear file).
Now, my pom.xml inside my log4j module is this one :
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
I have this build error :
30/10/12 18:56:07 CET: Build errors for log4j; org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal on project log4j: Could not resolve dependencies for project com.sim:log4j:jar:0.0.1-SNAPSHOT: Could not find artifact com.sim:log4j:jar:0.0.1-SNAPSHOT
I thought that there was some dependency problem since sim-java use com.sim.log4j as transitive dependency, so I tested that inside log4j pom.xml :
<dependencies>
<dependency>
<groupId>com.sim</groupId>
<artifactId>sim-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.sim</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
30/10/12 18:59:22 CET: [WARN] The POM for com.sim:log4j:jar:0.0.1-SNAPSHOT is missing, no dependency information available
30/10/12 18:59:22 CET: Missing artifact com.sim:log4j:jar:0.0.1-SNAPSHOT:provided
30/10/12 18:59:22 CET: Missing artifact com.sim:log4j:jar:0.0.1-SNAPSHOT:provided
30/10/12 18:59:22 CET: Missing artifact com.sim:log4j:jar:0.0.1-SNAPSHOT:provided
Perhaps including com.sim.log4j inside modules (ejb, web etc...) would work but I want to use transitive dependency via sim-java project.
How to do this please ?
Olivier

You cannot have the dependency on com.sim:log4j in the parent pom. That dependency will be inherited in the children meaning that com.sim:log4j will depend on itself.
Instead create a <dependencyManagement/> in the parent pom and then declare the use of com.sim:log4j in the children that needs it, here it is web and ejb.
Parent pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sim</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
Web and Ejb pom:
<dependencies>
<dependency>
<groupId>com.sim</groupId>
<artifactId>log4j</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
Edit
You can still have a transitive dependency by only having the dependency on the log4j module from the ejb project. The web project will then have a dependency on the ejb project and the log4j will be a transitive dependency.

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.

Eclipse plugin- Maven transitive dependency issue

I am facing issue with velocity jar issue. As one of the eclipse plugin dependent on CXF bundle.
jar dependency defined in pom.xml as below,
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle</artifactId>
<version>2.7.5</version>
</dependency>
another eclipse plugin dependent on custom bundle jar which has
jar dependency defined in pom.xml as below,
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
On runtime I am geting issue as,
Could not find Velocity template file: org/apache/cxf/tools/wsdlto/frontend/jaxws/template/build.vm
To identify the issue I run the command,
mvn dependency:tree -Dverbose
This shows maven omitting velocity jar from cxf as it loads another velocity in classpath.
How to resolve this jar dependency ?
use the <exclusions> tag for the dependency you not want:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</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.

slf4j-log4j12 not packaged by maven with "runtime" scope

I have a project managed by maven with slf4j-api-1.5.8 and log4j-1.2.14 dependencies.
At runtime, slf4j needs slf4j-log4j12-1.5.8.jar to "bridge" output to log4j.
So in pom.xml , I add this dependency :
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
After building (war:war) , log4j-1.2.14.jar and slf4j-api-1.5.8.jar are both added to WEB-INF/lib directory , but I cannot find slf4j-log4j12-1.5.8.jar within!
I then use "Dependency Hierarchy" to check the resolved dependencies , but cannot find slf4j-log4j12 (so it's not packaged into WEB-INF/lib)
What's going wrong here?
environment : maven 3.0-beta1 , m2-eclipse-0.10.0.20100209
The dependency management section is a mechanism for centralizing dependency information, adding a dependency in the dependency management section doesn't make it a dependency of your project by itself, you still need to declare it as dependency:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
</dependencies>

Resources