Utkarsh Mishra
Utkarsh Mishra

Reputation: 490

Maintaining two different Spring boot versions in single Maven package

Let's say we have a shared-lib package. The pom for the same is as follows:

<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>com.project.microservice-a</groupId>
<artifactId>shared-lib</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>shared-lib</name>

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

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <start-class>com.projects.lib1.Application</start-class>
    <java.version>1.8</java.version>
</properties>
....
....
</project>

There are projects using above shared library, having following pom.xml

<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>com.projects.microservice</groupId>
<artifactId>accounts</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>accounts</name>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
    <dependencies>
    <dependency>
        <groupId>com.project.microservice-a</groupId>
        <artifactId>shared-lib</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
....
<dependencies>

Then there is one special subsystem running on Spring-boot-starter-parent.1.3.5 as parent, which won't take shared-lib with Spring-boot-starter-parent-1.2.3.

For importing shared-lib with Spring-boot.1.3.5, we need to modify pom.xml with parent as Spring 1.3.5 version and then build. This causes maintenance issues while building all subsystems, as Jenkins CI builds all JARs from Github with master branch. We can specify a separate branch manually, but maintaining same code for two branch is plain repetition.

Can anyone suggest a solution, which IMO may be a way to achieve one of these:

  1. Create a package embedding both Spring 1.2.3 and Spring 1.3.5, and specifying required dependency version in other subsystems.

  2. Bulid original client package with Spring Boot 1.3.5, and force it to use older version of Spring boot when used a dependency in required subsystems.

Upvotes: 3

Views: 4526

Answers (1)

Anton Koscejev
Anton Koscejev

Reputation: 4857

Let's say these are your dependencies for each project:

  1. shared-lib:
    • spring-boot-foo:1.2.3
  2. project-a:
    • shared-lib
    • spring-boot-bar:1.2.3
  3. project-b:
    • shared-lib
    • spring-boot-baz:1.3.5

Now you want project-a to use 1.2.3 of all spring-boot libraries, and project-b to use 1.3.5, regardless of what spring-boot libraries shared-lib specifies?

Put the following in your pom.xml:

<properties>
    <spring-boot.version>1.3.5.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

If your projects have a common parent pom.xml, you can put it there and simply change spring-boot.version value to something else per-project as you see fit. Otherwise you'll have to duplicate it.

Alternatively if this so-called BOM (<scope>import</scope>) doesn't work, you can list each dependency explicitly, e.g.:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-foo</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-bar</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-baz</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Read more about managing spring-boot dependencies: http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html

UPDATE:

You can manage other dependencies the same way as necessary. For example:

<properties>
    <spring-data-releasetrain.version>Gosling-SR4</spring-data-releasetrain.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>${spring-data-releasetrain.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

Upvotes: 1

Related Questions