hi folks. I have an internal framework which can b...
# dependency-management
m
hi folks. I have an internal framework which can be consumed by both Maven and Gradle consumers. One of the issues is getting similar dependency graphs in Gradle and Maven. With its "nearest" strategy, folks tend to fix dependency conflicts by adding a dependency which appears "before", typically in a dependency management section. So far so good. In Gradle, all dependency management blocks are considered, which I think is a cleaner strategy. However, I'm facing a problem which I think is a bug in Gradle (thread).
here's the error message:
Copy code
> Could not resolve <http://jakarta.ws.rs:jakarta.ws.rs-api:3.1.0|jakarta.ws.rs:jakarta.ws.rs-api:3.1.0>.
     Required by:
         project :micronaut-test-native > io.micronaut.platform:micronaut-platform:4.3.4 > io.micronaut.jaxrs:micronaut-jaxrs-bom:4.3.0
      > Cannot find a version of '<http://jakarta.ws.rs:jakarta.ws.rs-api|jakarta.ws.rs:jakarta.ws.rs-api>' that satisfies the version constraints:
           Dependency path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'secret:secret-identity:0.9.122-SNAPSHOT' (runtimeElements) --> 'secret:secret-http:0.9.122-SNAPSHOT' (runtimeElements) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:{strictly|jakarta.ws.rs:jakarta.ws.rs-api:{strictly> 2.1.6}'
           Constraint path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'io.micronaut.platform:micronaut-platform:4.3.4' (runtimeElements) --> 'io.micronaut.jaxrs:micronaut-jaxrs-bom:4.3.0' (runtimeElements) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:3.1.0|jakarta.ws.rs:jakarta.ws.rs-api:3.1.0>'
           Dependency path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'secret:secret-identity:0.9.122-SNAPSHOT' (runtimeElements) --> 'com.oracle.oci.sdk:oci-java-sdk-addons-internal:3.37.0' (runtime) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:2.1.6|jakarta.ws.rs:jakarta.ws.rs-api:2.1.6>'
           Dependency path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'secret:secret-identity:0.9.122-SNAPSHOT' (runtimeElements) --> 'secret:secret-jaxrs-bridge:0.9.122-SNAPSHOT' (runtimeElements) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:{strictly|jakarta.ws.rs:jakarta.ws.rs-api:{strictly> 2.1.6}'
           Dependency path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'secret:secret-identity:0.9.122-SNAPSHOT' (runtimeElements) --> 'secret:authentication-client:2.3.30' (runtime) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:2.1.6|jakarta.ws.rs:jakarta.ws.rs-api:2.1.6>'
           Dependency path 'secret:micronaut-test-native:0.9.122-SNAPSHOT' --> 'secret:secret-identity:0.9.122-SNAPSHOT' (runtimeElements) --> 'secret:sdk:2.3.30' (runtime) --> '<http://jakarta.ws.rs:jakarta.ws.rs-api:2.1.6|jakarta.ws.rs:jakarta.ws.rs-api:2.1.6>'
In Maven, the resolved version is
<http://jakarta.ws.rs:jakarta.ws.rs-api:2.1.6|jakarta.ws.rs:jakarta.ws.rs-api:2.1.6>
, which is what we expect. However, the Micronaut BOM wants it upgrade to 3.1.0, so Gradle resolves 3.1.0 (optimistic upgrade), which is a bit too optimistic.
so what I've done is setting version
2.1.6
as a strict version. However, strict gives me this error.
Given that a "strict" dependency should win over a "requires" or "prefer", I think that this should actually pass.
note that I also tried with strictly [2.1.6, 3[, prefer 2.1.6 but it fails the same
I don't understand why 2.1.6 is rejected here...
t
Because it actually conflicts with 3.1.0. The 3.1.0 dependency (constraint) says the dependency cannot be lower than 3.1.0, and "strictly 2.1.6" that it cannot be anything else than 2.1.6, so Gradle complains about the conflict. I think you'd need to use a dependency resolve rule or something like that.
m
thing is, in my (poor) memory, a strict dependency wins over a require
a dependency rule is not possible, because they cannot be consumed (like a pom.xml)
m
"On a declared dependency, a strictly can downgrade a version"
that's actually what I remember coding 😄
strictly should fail if 2 strict dependencies disagree
otherwise it should downgrade
v
Exactly
m
(that was to provide a better replacement for
force
)
in this case, there's a single strict version, the one I'm providing, but it still fails, which I think is a bug
v
From the output you shared, I'd say the same
But there is for sure something more to it 😄
m
I will summon a dependency management expert I know next week if there's no update :)
v
And why does it say "Could not resolve jakarta.ws.rs:jakarta.ws.rs-api:3.1.0", when it then says it cannot decide on a version. Seems it did decide already. 😕
m
ahhh you know, error messages 🙂
v
Yeah, also possible
Ah, error messages, you know
You have a conflict between two strict versions
https://repo1.maven.org/maven2/io/micronaut/platform/micronaut-platform/4.3.4/micronaut-platform-4.3.4.module
```[...]
{
"group": "io.micronaut.jaxrs",
"module": "micronaut-jaxrs-bom",
"version": {
"requires": "4.3.0"
},
"attributes": {
"org.gradle.category": "platform"
},
"endorseStrictVersions": true
},
[...]```
=> constraints in
micronaut-jaxrs-bom
are strict =>
3.1.0
is strict
=> boom
m
mmm, there should be no strict version in jaxrs-bom, we can't generate these in micronaut so it'd be surprising
v
That's why you get a big fat error when you try to publish with an enforced platform 😄
m
endorseStrictVersion is a differnet thing
v
Oh, is it?
Whatever it is supposed to do, I guess it causes your error maybe. 😄
m
yes, it only changes the semantics if the target platform has strict versions
v
oh, ok
Maybe that's just the intention? 🙂
m
no, should it be the case all builds in the world would be failing
v
Like
tasks.named { ... }
which should behave differently than
tasks.matching { ... }
but isn't
Oh, ok
m
I really tend to think it's a bug, but...
v
Can you knit an MCVE? Just doing
Copy code
dependencies {
    implementation(platform("io.micronaut.platform:micronaut-platform:4.3.4"))
    implementation("<http://jakarta.ws.rs:jakarta.ws.rs-api:2.1.6!!|jakarta.ws.rs:jakarta.ws.rs-api:2.1.6!!>")
}
works fine
m
I think the issue arises with 2 platforms, like I have here
v
Which second platform? I see only 5 dependency paths and one contraint path in the error message.
m
I'm actually wondering why it doesn't appear in the message
the constraint is added via a platform
t
From the links I shared, you only quoted part of it. The next sentence reads: > When on a transitive dependency, it will cause dependency resolution to fail if no version acceptable by this clause can be selected. (though I have to admit "on a transitive dependency" is not very clear to me) And https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html#sec:strict-version-consequences seems to describe a similar situation to yours IIUC.
v
What do you try to say Thomas? Still that it fails due to
strict
not being able to downgrade? Because
strict
is the tool of choice to downgrade a version unless you need a big-hammer or non-published-hammer and use
force
which even overrides strict versions iirc.
The case described at your last link describes two conflicting
strict
versions
m
maybe that subgraph story... it's too hard to reason for a friday evening
v
Which according to the output above is not the case
m
I think I'll have to write a plugin which simply parses my platform catalog and uses resolution rules to force everything. That would be acceptable in my case since I'm in a particular case. Adds a plugin to apply, but well...
Anyway thanks for the inputs, guys!
👌 1