Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MAVEN! Spring Boot takes wrong dependency version mentioned in dependency project

I have two Spring Boot projects, and want to use one of them as MAVEN dependency in other.

  • Project Scraper depends on Database project
  • Project Database contains database layer (Entities and DAO are build and tested here)

In Database project I have to override the Hibernate version, and did like described in https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot option 2.

<properties>
...
    <hibernate.version>5.2.10.Final</hibernate.version>
</properties>

This works fine and I see proper version in MAVEN depdndencies for Database project: /home/pm/.m2/repository/org/hibernate/hibernate-core/5.2.10.Final/hibernate-core-5.2.10.Final.jar

Than I come to Scraper project. It not contain any Hibernate in Maven dependencies, as I not import them explicitly. Now I add my Database prject dependency

    <dependency>
        <groupId>web.scraper.database</groupId>
        <artifactId>DataBase</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

And this imports hibernate as well, but with wrong version (version mentioned in Spring parent pom, instead of my Database project Hibernate version) /home/pm/.m2/repository/org/hibernate/hibernate-core/5.0.12.Final/hibernate-core-5.0.12.Final.jar

I want to get hibernate version mentioned in Database project dependecy. Ho to do this?

I would like to not override Hibernate version in Scraper project.

Scraper/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>web.scraper.engine</groupId>
    <artifactId>Scraper</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Scraper</name>
    <description>Web scraper application</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>web.scraper.database</groupId>
            <artifactId>DataBase</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Database/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>web.scraper.database</groupId>
    <artifactId>DataBase</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>DataBase</name>
    <description>Data base model and DAO</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <!-- Need to set Hibernate version explicitly,
        because java 8 date and time not mapped properly
        with default version -->
        <hibernate.version>5.2.10.Final</hibernate.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <!-- 
            <scope>runtime</scope>
             -->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- This makes H2 web console available -->
        <!-- 
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
        -->             

<!-- 
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
 -->

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.4.1.Final</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
like image 741
Pavlo Morozov Avatar asked Oct 17 '22 08:10

Pavlo Morozov


2 Answers

To coordinate dependencies between projects, you should introduce a parent pom that both projects inherit from. The parent project itself can inherit from the Spring Boot parent pom. All dependency version overrides via properties should occur in your new parent pom, something like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>web.scraper</groupId>
    <artifactId>Parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>Parent</name>
    <description>Parent pom to coordinate dependencies</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <!-- Need to set Hibernate version explicitly,
        because java 8 date and time not mapped properly
        with default version -->
        <hibernate.version>5.2.10.Final</hibernate.version>
    </properties>

    <!-- Optionally, you can make this parent define a multi-module project, 
         so that the artifacts can be built together, but you don't have to. -->
    <modules>
        <module>Scraper</module>
        <module>Database</module>
    </modules>
</project>

And then, in your Scraper and Database poms, declare the parent like so:

<parent>
    <groupId>web.scraper</groupId>
    <artifactId>Parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent, or make a multi-module project -->
</parent>

Additionally, any new dependencies that you need to add that are not managed by spring, can be added to the <dependencyManagement> section of the parent pom, so that your other poms never have to declare versions.

With this in place, mvn dependency:tree | grep hibernate-core shows the correct versions in both projects:

[INFO] |  +- org.hibernate:hibernate-core:jar:5.2.10.Final:compile
like image 182
derickson82 Avatar answered Nov 02 '22 13:11

derickson82


You can force the proper version. In your scraper project, from within your database dependency tag, exclude the Hibernate dependency.

<exclusions>
  <exclusion>  
    <groupId>sample.ProjectB</groupId>
    <artifactId>Project-B</artifactId>
  </exclusion>
</exclusions> 

Maven Optional Dependencies and Dependency Exclusions

Obviously, replace the sample.ProjectB stuff with the Hibernate info. Then, you just include a separate dependency for the version of Hibernate that you want.

I think there is a simpler way to do this all within the database dependency in your scraper project but I can't find it ATM and I don't have much time.

Also of note/help:

  • Forcing a version
  • Intro to the Dependency Mechanism

EDIT: based on our comments, try excluding Hibernate from the first Spring dependency so that Spring is not able to pass it on to the scraper project.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
  <exclusions>
    <exclusion>  
      <groupId>HIBERNATE-STUFF</groupId>
      <artifactId>HIBERNATE-STUFF</artifactId>
  </exclusion>
</exclusions> 
</dependency>

This would be the Spring dependency in the database file. Have a separate dependency for the version of Hibernate you want.

As a side note, give these a spin. They can help spot what's coming from where:

mvn dependency:tree -Dverbose 
mvn dependency:tree -Dverbose | grep 'omitted for conflict'
like image 20
Old Schooled Avatar answered Nov 02 '22 11:11

Old Schooled