This message was deleted.
# general
s
This message was deleted.
c
Adding further to this… the following is a draft I’m working on to add the conversation on the “broken metadata issue”:
This is great and all... but none of this works if a Gradle user has turned on
failOnVersionConflict()
. The ultimate problem here seems to be that Jackson wants to use micro-versions for security fixes to individual packages, but the current system of BOMs and intermodule dependency declarations that connect the Jackson modules doesn’t account for this.
I believe there are two outstanding issues here:
1. The Gradle module metadata published with each modules links the modules back to the originally released 3-digit BOM version only. I think that should probably be a range:
[2.13.2,2.13.3)
to correctly capture that “aligned” could mean using a module that has no security fixes with a BOM that captures security fixes.
2. The intermodule dependencies are “fixed” and not version ranges. If security fixes are done using the fourth digit, then dependencies on central modules like
jackson-core
or
jackson-databind
should capture that using appropriate ranges. Of course currently this is indirectly tied back to the parent POM which does the central dependency management for the whole system, which is also the BOM for the system - I fear that fact might make things yet more complicated.
You can see some that “fear” coming out in the dependency graph of the security fixed
jackson-databind:2.13.2.1
where the POM ‘parent’ chain looks like this:
jackson-databind:2.13.2.1 -> jackson-base:2.13.2.20220324 -> jackson-bom:2.13.2.20220324
- that’s all great. However the dependency management in
jackson-bom
then pins other modules to 2.13.2 which ends up pulling the 2.13.2 BOM as well, which stands in conflict. I wonder if this is even fixable without decoupling the POM parent from the BOM?
l
The combination of partial releases (only have a set of submodules with 4 digit versions) and explicit alignment with Gradle Module Metadata (all modules reference the Jackson BOM in their GMM) seems indeed to be a case that requires deeper thinking into the versions to use for these cross references. It could be interesting to validate the range usage through component metadata rules, to confirm this works. Note: I did not read the Jackson issues.
j
Sorry I don’t understand what the problem is. There was an issue because micro patches are not aligned in version numbers. But we found a good solution and there is no more wrong metadata published. (See resolution of https://github.com/FasterXML/jackson-databind/issues/3428)
"requires": "[2.13.2,2.13.3)"
in published metadata is a very bad Idea IMO. It’s an open range which makes a build not reproducible. Ranges alone should never be used in published metadata.
c
Thats not an open range… it’s a closed range that corresponds to the contract between the Jackson modules. Anything within that range interoperates. That said, let me try and pull together an example that shows the problem I’m seeing.
j
Ah now I see the “failOnVersionConflict”. I think “failOnVersionConflict” is just not compatible anymore with the newer dependency management concepts here. Using it just interferes with so many other useful things Gradle has now. In my opinion it should be deprecated and replaced with something better (or just remove). I don’t see how we can change the situation in Jackson without having “a conflict” unless Jackson itself aligns the BOM versions with the micro-patch versions (which I proposed, but it does not fit the current process)
Thats not an open range…
Sorry wrong wording I used. Point is that it is a range. Once there is a new micro release of the BOM, resolution results automatically change in your build.
c
I think it’s possible to make this work by separating the jobs of the parent pom dependency management section, and the BOM dependency management section: 1. The parent POM should capture the version compatibility rules for a “release”. So for the 2.13.2 release that would be
[2.13.2,2.13.3)
, so as to cover any future security fixes. 2. The BOM should capture a specific set of artifacts (no ranges allowed). 3. No Jackson module should ever pull in a BOM. The existing version alignment mechanism that Jackson uses covers the scenario where the “compatibility rules” are “everything must be the same version”. That’s explicitly not true here, hence the existing scheme doesn’t work.
I’ll agree that use of
failOnVersionConflict()
is rare… but I would argue it is correct. Anyone not using this is inviting optimistic version conflict resolution to substitute a very specific looking
1.2.3
with the truly open range:
[1.2.3,)
. Then they’re just relying on their own (and all downstream consumers) testing to make sure things don’t break.
j
@Chris I have to apologise that I did not fully understand the problem initially. I see now, that even the solution I called “good” on the Jackson issue, it is not working with
failOnVersionConflict()
. I think there is no way to implement the alignment-through-bom pattern (https://blog.gradle.org/alignment-with-gradle-module-metadata) without always causing a version conflict If the component versions are not always the same (as it is the case for micro-patches in Jackson). Because then the same version of a component may be referenced in multiple BOM versions, but the component can only reference one BOM version (the one that was available when the component was published). So if we want to keep the
failOnVersionConflict()
case working, I think the only option is to remove the Gradle Metadata again from Jackson completely and not have the alignment pattern in there anymore. @Louis Jacomet could you or someone else give a comment on where Gradle stands here officially? What’s the stance towards
failOnVersionConflict()
?
c
and just for my amusement…
Copy code
$ git --no-pager log -SfailOnVersionConflict
commit b0ff92221a9565e8079101da2973d27819f935bf
Author: Chris Dennis <chris.w.dennis@gmail.com>
Date:   Thu Apr 29 14:01:32 2021 -0400

    Convert from cross-project configuration to convention plugins

commit ed94e7e7ec9bb659b3cf0b6c08f5a25c48d6c867
Author: Louis Jacomet <louis.jacomet@terracottatech.com>
Date:   Thu Aug 24 21:29:05 2017 +0200

    Migrate to Gradle 4.3.1
    
    Seriously improves overall build time
    Especially when simply wanting to build a kit or run all tests.
🤣
😉 1
l
Because of the micro patches strategy of Jackson, alignment and
failOnVersionConflict
are at odds indeed. As indicated by Jendrik, adding ranges to published version can be tricky as it might causes changes in resolution whenever a patch version appears. So I am not sure there is a general answer for this problem. One option that could be tried on the Jackson end would be to do the alignment with ranges, as suggested by Chris, but also specifying the base release as a
prefer
. This would make sure that the base version is always selected unless a patch version enters the graph explicitly. I have not tested this so it might still be a problem with
failOnVersionConflict
in some corner cases.
j
I gave it a quick try, but unfortunately it also gives a conflict (as I wound have expected). Because the prefers leads to a selection which is then in conflict with the higher version: https://scans.gradle.com/s/kmzgoq4qnw2fw/dependencies?focusedDependency=WzAsMCwxLFswL[…]d=W1swXSxbMCwwXSxbMCwwLFswXV0sWzAsMCxbM11dLFswLDAsWzAsMV1dXQ As I said, I think many of these newish rich version things are just not well combinable with
failOnVersionConflict
. Without the
failOnVersionConflict
I think it’s quite neat that the approach even supports alignment with the additional micro versions. Not sure what to do now. 🤔