Search code examples
javaspring-bootmavenqpidspring-boot-starter-parent

Spring boot starter dependency overwrites netty version of the qpid-jms-client


I'm using the QPID-JMS-ClIENT (version 0.59.0) in a spring boot project. I would like to overwrite the netty-version since this version of QPID comes with the netty-version: 4.1.63.Final [1]. I would like to overwrite the netty version to the newest: 4.1.68.Final. I also use the spring-boot-starter-parent (version: 2.3.12.RELEASE) in my POM as parent pom which also comes with a netty version (4.1.65.Final). I'm aware the spring boot version is rather old and should be updated. Anyway, it seems like the spring-boot-starter-parent enforces its netty version.

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>

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

    <groupId>org.example</groupId>
    <artifactId>untitled1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.qpid/qpid-jms-client -->
        <dependency>
            <groupId>org.apache.qpid</groupId>
            <artifactId>qpid-jms-client</artifactId>
            <version>0.59.0</version>
        </dependency>
    </dependencies>
</project>

Since I don't make use of any spring boot dependency I don't understand why the netty version is set to 4.1.65.Final:

[INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ untitled1 ---
[INFO] org.example:untitled1:jar:1.0-SNAPSHOT
[INFO] \- org.apache.qpid:qpid-jms-client:jar:0.59.0:compile
[INFO]    +- org.slf4j:slf4j-api:jar:1.7.30:compile
[INFO]    +- org.apache.geronimo.specs:geronimo-jms_2.0_spec:jar:1.0-alpha-2:compile
[INFO]    +- org.apache.qpid:proton-j:jar:0.33.8:compile
[INFO]    +- io.netty:netty-buffer:jar:4.1.65.Final:compile
[INFO]    +- io.netty:netty-common:jar:4.1.65.Final:compile
[INFO]    +- io.netty:netty-handler:jar:4.1.65.Final:compile
[INFO]    |  +- io.netty:netty-resolver:jar:4.1.65.Final:compile
[INFO]    |  \- io.netty:netty-codec:jar:4.1.65.Final:compile
[INFO]    +- io.netty:netty-transport:jar:4.1.65.Final:compile
[INFO]    +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.65.Final:compile
[INFO]    |  \- io.netty:netty-transport-native-unix-common:jar:4.1.65.Final:compile
[INFO]    +- io.netty:netty-transport-native-kqueue:jar:osx-x86_64:4.1.65.Final:compile
[INFO]    \- io.netty:netty-codec-http:jar:4.1.65.Final:compile

The pom of the QPID-JMS-CLIENT defines the netty version by the property netty-version[3] while spring boot uses the netty.version. If I overwrite the property of spring boot the version of QPID is changed:

...
<properties>
    <netty.version>4.1.68.Final</netty.version>
</properties> 
...

If I overwrite the version of QPID there is no effect at all:

...
<properties>
    <netty-version>4.1.68.Final</netty-version>
</properties> 
...

So my questions are:

  • Why does maven enforces the parent poms netty version while the dependency comes with an explicit different version? (Even if I lower spring boots version the netty dependency is set to that version)
  • How do I overwrite the version of netty correctly?

Regards

[1] https://mvnrepository.com/artifact/org.apache.qpid/qpid-jms-client/0.59.0

[2] https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent/2.3.12.RELEASE

[3] https://github.com/apache/qpid-jms/blob/main/pom.xml#L40


Solution

  • Your pom will be inheriting a dependencyManagement section from the spring poms you have used in its parent hierarchy. That ancestry includes spring-boot-dependencies which is managing the netty version (importing netty-bom using the netty.version property as you seem to already realise).

    As such, the dependencyManagement in your effective pom (viewable with mvn help:effective-pom) will be governing the version of netty that is selected. The version of netty the client pom specified becomes irrelevant to what your application uses, as the version is actually being overridden and managed by your build. Thats one of the key uses for dependencyManagement config.

    If you want to override the version of netty locally while having that parent heirarchy you would either use the netty.version property relating to the inherited dependencyMangement from the parent, as you have already noted, or you could define your own local dependencyMangement for netty in your pom which overrides the inherited parent management of it.