Avoid child dependencies override parent dependencies using Maven 3 - java

I'm using multiple spring based maven repositories in a web project, and I'm having problems with the dependencies used by child POM.
I have a parent POM like this:
<dependencyManagement>
<dependencies>
<!-- SPRING -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SPRING SECURITY -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>4.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SPRING BOOT -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SPRING WS -->
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<!-- OTHER DEPENDENCIES OMITTED -->
</dependencies>
</dependencyManagement>
And a child POM like this:
<dependencies>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<!-- OTHER DEPENDENCIES OMITTED -->
</dependencies>
As far as my understanding of maven exclusion goes, this should avoid the overriding of the parent POM version, but due to the fact that spring-ws-security depends on a lower version of spring-core (4.0.9) whose method have been changed I can't deploy the app on a tomcat local server because of a NoSuchMethodError Exception, which can be also triggered when the app is actually deployed but the dependences to the old spring-core version remains.
How can I avoid this overriding of dependencies?
Or is there some way of using both dependencies (which as far as I've searched is not secure)?
Links visited already:
Similar problem, but from child to parent,
Exclusions example
Just a few mentions, I've visited others as well but forgot the links.
Edit: spring-ws dependencies use spring 4.0.9 which is overriding the 4.3.0 version (the one I need to use) I've defined in the parent POM.
+- org.springframework.ws:spring-ws-core:jar:2.2.3.RELEASE:compile
[INFO] | | | +- org.springframework:spring-oxm:jar:4.3.0.RELEASE:compile (version managed from 4.0.9.RELEASE)
[INFO] | | | +- org.springframework:spring-web:jar:4.3.0.RELEASE:compile (version managed from 4.0.9.RELEASE)
[INFO] | | | \- org.springframework:spring-webmvc:jar:4.3.0.RELEASE:compile (version managed from 4.0.9.RELEASE)

You can simply do explicit override in your child pom by mentioning the version 4.0.9, like below.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.9</version>
</dependency>
As quoted below, this version will affect the child-of-child pom, if any.
Forcing a version
A version will always be honoured if it is declared
in the current POM with a particular version - however, it should be
noted that this will also affect other poms downstream if it is itself
depended on using transitive dependencies.

Related

Issues with version management in maven

The problem I encountered is this, here is the definition in my POM file.\
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
In this dependency, It's having a sub-dependency which is starter-tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.0.0.RELEASE</version>
<scope>compile</scope>
</dependency>
But In my maven tree
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.0.0.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.3.6.RELEASE:compile
By the way this project have a parent, In parent There is a 2.3.6 starter-webdependency.
I want to know why the sub-dependency starter-tomcat in the web-starter I referenced 2.0.0 is not the 2.0.0 I see, but 2.3.6 in the parent dependency.
I got it.
There are two ways to solve this question
exclude your sub-dependency and add a new version dependency.
use to control this denpendency

Where are the versions of the other spring modules specified in the pom file of spring-data-redis 2.6.1

Maven novice here. The pom file of the Spring Data Redis module version 2.6.1 can be found at https://repo1.maven.org/maven2/org/springframework/data/spring-data-redis/2.6.1/spring-data-redis-2.6.1.pom. The spring-aop, and a bunch of other Spring modules don't have a version specified in the file, but when I look at the dependence tree, the version is 5.3.15.
So where is the version specified?
They come from the parent, which is org.springframework.data.build:spring-data-parent:2.6.1. That POM contains a dependencyManagement section:
<properties>
…
<spring>5.3.15</spring>
…
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
…
</dependencies>
</dependencyManagement>
And that spring-framework-bom, called a Bill of Materials (AKA BOM), has all the version of various Spring libraries.
When you import that BOM in your project, the versions listed in its dependencyManagement section become kind of recommendations: they will be used if no other version is specified:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.15</version>
</dependency>
</dependencies>
…
</dependencyManagement>

How does Spring Boot provide spring-data-jpa v1.10.3.RELEASE

I have a project with a POM which specifies the dependency on spring-data-jpa like below:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
It is not with the version number, however when I run mvn:dependency:tree I can see the relevant section like below ...
| \- org.springframework:spring-orm:jar:4.3.3.RELEASE:compile
[INFO] +- **org.springframework.data:spring-data-jpa:jar:1.10.3.RELEASE**:compile
[INFO] | +- org.springframework.data:spring-data-commons:jar:1.12.3.RELEASE:compile
[INFO] | \- org.aspectj:aspectjrt:jar:1.8.9:compile
[INFO] +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] +- org.hibernate:hibernate-core:jar:5.0.11.Final:compile
... it shows it is with version 1.10.3.RELEASE.
I wonder how does it finally comes with the version number. I looked up, it is neither latest Maven Repository's Spring Data JPA version number nor there is a section in its parent POM defining that dependency. The project POM is like below:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot</artifactId>
<version>${camel-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
The version of spring-data-jpa is provided by the spring-boot-parent.
You can see the relationship between spring-boot version and spring-data-jpa in the appendix-dependency-versions section of the Spring Boot docs.
For example, the latest version of Spring Boot will provide version 1.11.9.RELEASE of spring-data-jpa.
In your question you show: org.springframework.data:spring-data-jpa:jar:1.10.3.RELEASE this suggests that you are using v1.4.x of Spring Boot, the relevant dependency is shown in the docs for v1.4.1 of Spring Boot:
org.springframework.data spring-data-jpa 1.10.3.RELEASE
The relationship between spring-boot 1.4.1.RELEASE and spring-data-jpa 1.10.3.RELEASE is facilitated by Maven, since Maven follows the relationships defined in Spring Boot's POMs.
From the docs (my emphasis):
Each release of Spring Boot provides a curated list of dependencies that it supports. In practice, you do not need to provide a version for any of these dependencies in your build configuration, as Spring Boot manages that for you.
The curated list contains all the spring modules that you can use with Spring Boot as well as a refined list of third party libraries. The list is available as a standard Bills of Materials (spring-boot-dependencies) that can be used with both Maven and Gradle.
So, Spring Boot provides spring-boot-starter-data-jpa for you which in turn provides spring-data-jpa via a dependency on spring-data-releasetrain. The precise mechanism for this is:
spring-boot-starter-data-jpa declares a dependency on spring-data-jpa.
spring-boot-starter-data-jpa is parented by spring-boot-starters
spring-boot-starters is parented by spring-boot-parent
spring-boot-parent is parented by spring-boot-dependencies
spring-boot-dependencies imports the spring-data-releasetrain POM:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>${spring-data-releasetrain.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>

Maven dependency exclusion is not working as expected

I have added a dependency in my parent pom under dependecymanagement.
ParentPom
<dependecyManagement>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>some version</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencyManagement>
In my child pom I am simply inherting the dependecy without version
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
When I do dependency tree on my child pom its still showing commons-logging in tree which is excluded in parent pom .
mvn dependency:tree -Dverbose -Dincludes=commons-logging:commons-logging
This is the dependecy tree from child.
[INFO] \- org.springframework:spring-core:jar:parent version .RELEASE:compile
[INFO] \- commons-logging:commons-logging:jar:some version:compile
Though version no is getting inherited why not excluded dependency is getting inherited from parent pom is what I am looking for.
Am I assuming anything wrong? or is that how maven behaves?
Valid solutions would be appreciated.
TIA

I can not use aries jpa/v2.0.0 and transactions/v2.0.0

I tried enable and int blueprint.xml but I have error. It is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://aries.apache.org/xmlns/jpa/v2.0.0
http://aries.apache.org/xmlns/transactions/v2.0.0 ">
<jpa:enable/>
<tx:enable-annotations/>
<service ref="userService" interface="domain.access.UserService"/>
<bean id="userService" class="domain.access.impl.UserServiceImpl" scope="singleton">
</bean>
</blueprint>
It is my dependencies in pom.xml I include all libs mabe I forgot somthing
<dependencies>
<dependency>
<groupId>sqljdbc41</groupId>
<artifactId>sqljdbc41</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.commons-dbcp</artifactId>
<version>1.4_3</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-validation_1.0_spec</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>kg.nurtelecom</groupId>
<artifactId>access-module-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>domain</groupId>
<artifactId>platform-common</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
and when I start bundle I have grace period and in log
2016-03-05 12:34:37,732 | INFO | l for user karaf | BlueprintContainerImpl | 15 - org.apache.aries.blueprint.core - 1.4.4 | Bundle kg.nurtelecom.access.module.impl/1.0.0 is waiting for name
space handlers [http://aries.apache.org/xmlns/jpa/v2.0.0, http://aries.apache.org/xmlns/transactions/v2.0.0]
In the transaction 2.0.0 namespace the xml element is named <tx:enable/> not <tx:enable-annotations/>. This is not related to the error you described though.
The error says that you do not have the correct Aries JPA bundle installed. Be sure you install all necessary features like in this example.
The dependencies in the pom cover only the build time. At runtime you have to provide the dependencies as karaf features or individual bundles.
Also make sure you use the newest Apache Karaf. Older versions did not include the aries transaction 2.0.0 bundle.

Categories

Resources