Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.x: overriding dependency versions in a Helidon application using a bom is unreliable #9651

Open
barchetta opened this issue Jan 10, 2025 · 2 comments
Assignees
Labels
build dependencies Pull requests that update a dependency file P3

Comments

@barchetta
Copy link
Member

barchetta commented Jan 10, 2025

Problem Description

If a user wants to override a third party dependency in their application by using a bom then this does not always work. Based on experimentation it seems like the general rule is:

  • If a version of a dependency is managed by importing a bom, then it can be overriden by importing a bom.
  • If a version of a dependency is managed by a direct entry in dependencyManagement (and not by importing a bom) then it can't be overriden by importing a bom

Therefore:

  • If a user application uses the Helidon application pom as their parent pom and therefore has dependencies/pom.xml in the parent chain.
  • And the third party dependency version is managed in dependencies/pom.xml by a direct entry in dependencyManagement (not by importing a bom)
  • Then the user application can not override the third party dependency version using a bom in their projects dependencyManagement.

On the other hand, these two variations work as expected:

  • If the user application imports dependencies/pom.xml as a bom instead of inheriting it (as is done in the standalone quickstarts) then then they can override the version with a bom.
  • If the user application overrides the version with a direct entry in their dependencyManagement then that also works.
  • And, of course, they can always set a version property to shape Helidon's dependency management (<version.lib.kafka>3.8.5</version.lib.kafka>).

Steps to reproduce

helidon init --version 4.1.6 --flavor MP --archetype quickstart --batch
cd quickstart-mp
mvn dependency:tree > t.out

Inspect t.out and you will see the version of all Jersey artifacts is 3.1.9

Next add this to the project's pom.xml:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.glassfish.jersey</groupId>
                <artifactId>jersey-bom</artifactId>
                <version>3.1.10</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Run mvn dependency:tree again and you'll see that some Jersey artifacts are 3.1.9 and others are 3.1.10. Helidon dependencies/pom.xml does import a bom to manage the Jersey version, but it also has some direct entries:

<artifactId>jersey-server</artifactId>

It looks like these direct entries are used to perform exclusions. In any case, the artifacts with direct entries stayed at 3.1.9, all other artifacts were overriden to 3.1.10.

If you repeat this experiment on the stand alone MP quickstart you will see that the Jersey version is correctly overridden for all artifacts, because the standalone quickstart imports dependencies/pom.xml instead of inheriting it.

Workaround

Setting the Maven property to shape Helidon's dependencies/pom.xml is the most robust way to upgrade a dependency. For example adding this to the application's pom results in all Jersey artifacts upgraded to 3.1.10:

    <properties>
        <version.lib.jersey>3.1.10</version.lib.jersey>
    </properties>

Another, more error prone, option is to add a direct dependency in the application's dependencyManagement section. For example adding this to the application's dependencyManagement results in version 3.1.10 of jersey-client being used:

            <dependency>
                <groupId>org.glassfish.jersey.core</groupId>
                <artifactId>jersey-client</artifactId>
                <version>3.1.10</version>
            </dependency>
@barchetta
Copy link
Member Author

barchetta commented Jan 10, 2025

Things we could do to improve this:

  1. Change the application poms to import dependencies/pom.xml into a dependencyManagement section (like the standalone quickstarts do) instead of inheriting it via the parent chain.
  2. Manage third party versions via boms whenever possible

@barchetta barchetta added 4.x Version 4.x dependencies Pull requests that update a dependency file and removed 4.x Version 4.x labels Jan 10, 2025
@barchetta
Copy link
Member Author

barchetta commented Jan 15, 2025

If we were to do number 1 above (change application poms to not have dependencies/pom.xml in the parent chain and instead import it as a bom), then this would introduce an incompatibility:

  • Maven properties in dependencies/pom.xml would not be available to application poms and application poms could not upgrade dependencies by setting these properties. That's a significant breakage as setting these properties to perform upgrades is the most robust way to force the upgrade of a third party.

We would need to take this into account if we restructured the parenting of the application poms. For example we might need to move the property definitions out of dependencies/pom.xml and into a new pom so that applications can include the new pom in their parent chain.

@barchetta barchetta self-assigned this Jan 16, 2025
@m0mus m0mus added the P3 label Jan 16, 2025
@m0mus m0mus moved this from Triage to Normal priority in Backlog Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build dependencies Pull requests that update a dependency file P3
Projects
Status: Normal priority
Development

No branches or pull requests

2 participants