[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-31 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17749174#comment-17749174
 ] 

Vladimir Sitnikov commented on MNG-7852:


{quote} Best would be to move this discussion to ML instead{quote}
Would you please clarify why do you think the issue belongs to ML rather than 
JIRA?
I do not understand the reason, and I do not want to get a "file JIRA instead" 
response on the ML.

{quote}Also, you mix runtime and compile time things ("nobody ensure that 
people can compile code")
{quote}
Correct me if I am wrong, but the full cite is "nobody ensures that people can 
compile code with the recent version {*}and supply an old version in the 
execution{*}". "and supply an old version in the execution" is important as 
otherwise, the bug won't trigger.

Correct me if I am wrong, but Java requires compile code before one can proceed 
with the execution, and it does matter which third-party libraries were present 
on the compilation classpath as it affects the resulting bytecode.
My example says that projects rarely ensure their jars can be safely downgraded.

{quote} You should do your homework{quote}
Sure thing.
Would you please respond to 
https://issues.apache.org/jira/browse/MNG-7852?focusedCommentId=17748173=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17748173
 or 
https://issues.apache.org/jira/browse/MNG-7852?focusedCommentId=17748217=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17748217
 ?
In my examples, the problematic transitive dependencies come from **other** 
dependencies, and I do not use the problematic ones directly.
I do not understand which of them you suggest to "declare as direct".
If you suggest declaring all the possible transitive dependencies (including 
transitives of transitives) as direct, then, well, the re-declaring 
dependencies approach is prone to errors I described in 
https://issues.apache.org/jira/browse/MNG-7852?focusedCommentId=17748677=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17748677.


> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first 

[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-31 Thread Tamas Cservenak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17749139#comment-17749139
 ] 

Tamas Cservenak commented on MNG-7852:
--

You are very wrong by putting statements like these, I'd really say this is 
FUD. Maven chooses "nearest" version and is predictable and even reproducible. 
And while blaming something else instead of yourself, due lack of knowledge 
about it, is really in human nature, don't fall for it.

Also, you mix runtime and compile time things ("nobody ensure that people can 
compile code"). Once you mention guava as runtime dependency, then you draw 
conclusion about code compilation. You should do your homework: if you compile 
against something, best practice is to declare it as direct dependency (and not 
rely on some 3rd level transitive dependency). Tools like Takari Lifecycle even 
ensure this: if you even touch a class that comes from any other dependency 
that first level ones (those in POM), your build will fail.

So please, stop bombing JIRA, as am still by my original statement: "Best would 
be to move this discussion to ML instead, preferably the users mailing list 
https://maven.apache.org/mailing-lists.html;

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-31 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17749133#comment-17749133
 ] 

Vladimir Sitnikov commented on MNG-7852:


{quote}There is no proper versions nevermind which version we choose during 
resolving transitive dependencies, alway we can have an incompatibilities 
between two versions.
{quote}
The current Maven's algorithm results in *{*}downgrading{*}* versions.
Downgrading dependency versions is very often an incompatible change.

On the other hand, upgrading a version is more likely to produce a workable 
classpath because many libraries maintain backward compatibility (== further 
versions are compatible with previous versions).

Let us quantify this.
Imagine lib-a with Guava 21 (see 
https://issues.apache.org/jira/browse/MNG-7852?focusedCommentId=17748217=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17748217)

Imagine I use lib-a in my project.
Imagine Maven selects Guava 19 for the runtime (e.g., another library 
introduced guava-19 a little bit earlier in the dependency tree).
Of course, the thing will fail at the runtime because lib-a might easily depend 
on a method added in guava-21.

Who will be to blame? Of course, {*}Maven would be to blame{*}, as it 
downgraded guava from 21 to 19.

Imagine an alternative case.
Imagine I use lib-a in my project.
Imagine Maven selects Guava 30 for the runtime.
Of course the thing might fail at the runtime (e.g. if Guava 30 accidentally 
fails to keep backward compatibility).

Who will be to blame in such case? Of course, {*}it would be Guava to blame{*}, 
and it is unlikely to break as Guava team tests backward compatibility.

In other words, almost no library tests for "forward compatibility". In other 
words, almost nobody ensures that people can compile code with the recent 
version and supply an old version in the execution.
At the same time, many teams verify backward compatibility. That means, 
upgrading dependencies is much safer than downgrading them.

 

The current Maven's algorithm seems to select semi-random transitive versions 
which are both unpredictable and might cause downgrades.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on 

[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-28 Thread Slawomir Jaranowski (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748682#comment-17748682
 ] 

Slawomir Jaranowski commented on MNG-7852:
--

[~vladimirsitnikov]  There is no {{proper versions}} nevermind which version we 
choose during resolving transitive dependencies, alway we can have an 
incompatibilities between two versions.

Enforcer rule can help to detect such situation, and yes you need redeclared 
dependencies in dep or depManagement in your project.

Finally tests unit and integration should confirm that your application is 
working.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-28 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748677#comment-17748677
 ] 

Vladimir Sitnikov commented on MNG-7852:


[~sjaranowski] , thanks for mentioning dependencyConvergence, however, I do not 
think it is a generally recommended solution unless you make the said enforcer 
rule enabled by default in all Maven installations.

enforcer does not help users "resolve the conflicts properly". I agree enforcer 
might make the dependency resolution issue easier to spot, however, it does not 
treat the root cause. The idea behind the current issue is to tune Maven's 
behaviour so it resolves proper versions in the first place rather than perform 
silent downgrades.
{quote}You need resolve conflicts in your project
{quote}
Could you please clarify what you mean by "resolve conflicts"? Correct me if I 
am wrong, but it means "re-declaring all (conflicting?) transitive 
dependencies" which is a bad idea because re-declared dependencies might get 
out of date (e.g. they might become stale, bad versions, and so on).

 

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-28 Thread Slawomir Jaranowski (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748666#comment-17748666
 ] 

Slawomir Jaranowski commented on MNG-7852:
--

Did you consider use 
https://maven.apache.org/enforcer/enforcer-rules/dependencyConvergence.html 
Then all artifacts without version conflict will be resolved as is. 
You need resolve conflicts in your project.

There is next rule which can help you:
https://maven.apache.org/enforcer/enforcer-rules/requireUpperBoundDeps.html  

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748323#comment-17748323
 ] 

Vladimir Sitnikov commented on MNG-7852:


Well, one of the workable algorithms is described at 
[https://docs.gradle.org/current/userguide/dependency_resolution.html#sub:resolution-strategy]

Of course, it would require rich versions (which would be useful in Maven 
anyway).

So it would make sense if Maven could consume and produce Gradle Module 
Metadata to resolve and use rich version declarations and dependency 
constraints.

With the new algorithm, many projects would just work since users often 
re-declare dependencies to avoid downgrades.

Of course, the ones who intentionally performed downgrade would need some 
treatment, however, I am sure there is a possibility to make the transition 
smooth. For instance, Maven could resolve the deps with two algorithms, and 
issue a warning when the results diverge

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Lenny Primak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748243#comment-17748243
 ] 

Lenny Primak commented on MNG-7852:
---

Hi,

I understand your points, and they are indeed valid. I myself ran into these 
problems.

However, your suggestion to "just remove" them is incomplete at best, as it 
would "break the world".

To make this wish a reality (which I am not sure it's possible) I would try to 
develop an enhancement of the algorithm that works and doesn't break any 
current projects.

As I said before, not sure that's possible.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748217#comment-17748217
 ] 

Vladimir Sitnikov commented on MNG-7852:


One more case (5):
 * I'm the author of my-lib
 * my-lib does not use guava, and it does not use guice
 * my-lib uses both lib-a and lib-b which are third-party libraries, and I have 
no direct control over them
 * lib-a uses guava 21 (==it depends on classes added in guava 21)
 * lib-a uses guice 5 (==it depends on classes added in guice 5, and it would 
fail with guice 3 on the classpath)
 * lib-b uses guava 23 (== it depends on a class that was added in guava 23, 
and it would fail with guava 21)
 * lib-b uses guice 3 (== it depends on a class that was added in guice 3)

In that case, Maven is doomed to resolve an incompatible configuration. It will 
not fail the build, but it would build an artifact that is throws errors in the 
runtime (either guava or guice would resolve to an too old version).

Once again, I understand that the workaround is to re-declare every possible 
version locally. However, well, what is the point of having "nearest first" 
strategy if it forces everybody to re-redeclare all the transitive versions?

Of course, I understand, that re-declaration is not that needed when there are 
no conflicts. Unfortunately, I do not understand how Maven users figure out if 
they have conflicts or not. All these problems would just go away if Maven 
considered all versions instead of "the first mentioned" ones.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748173#comment-17748173
 ] 

Vladimir Sitnikov commented on MNG-7852:


{quote}This "real life example" is totally along the lines of Maven specd 
behaviour
{quote}
Tamas, many thanks for your comments, however, I still struggle to figure out 
{*}{{*}}why{{*}}{*} Maven behaves like "nearest first".
The behaviour produces hard-to-reason failures, and it is unclear what could be 
the benefits of such an algorithm except "dumb-easy to implement".
{quote}As you (I guess) implied, this can be solved by multiple means, ideally 
by depMgmt. And yes, Maven makes you able to "not care", unlike Ant and others, 
where you need to enlist (and control) all the versions, with Maven you leave 
this to resolution. Or in other words, IF you care ("user has no control"), 
then use proper means like depMgt to sort out your issues.
{quote}
I am afraid I do not understand the suggestion here.
Imagine
 * I'm the author of my-lib
 * my-lib does not use guava
 * my-lib uses both lib-a and lib-b which are third-party libraries, and I have 
no direct control over them
 * lib-a uses guava 21 (==it depends on classes added in guava 21, and it would 
work fine with guava 23)
 * lib-b uses guava 23 (== it depends on a class that was added in guava 23 
only, and it would fail with guava 21)

What is your exact suggestion?

Do you suggest that I (as an author of my-lib) should explicitly mention 
"my-lib requires guava 23 on the runtime scope"? Of course, it would workaround 
the issue, however, it is exactly the duplication I do not like. As an author 
of my-lib, I do not really want to manually collect all the third-party 
transitive dependencies and figure out the compatible versions for them. I 
expect that dependency manager would do that.

At the same time, if I just add both dependencies on lib-a and lib-b, then 
Maven would resolve a *{*}random{*}* guava version depending on which of lib-a 
or lib-b was first on the list and/or which of them listed guava "closer to the 
dependency root". Please, acknowledge that "dependency deepness" is random, and 
I don't control which of lib-a or lib-b would put guava deeper.

In other words:
 * If I omit guava in my-lib, then Maven resolves random version, and I get 
crashes when Maven resolves guava 21 (e.g. lib-a was the first)
 * If I list guava in my-lib, then I would have to list every possible 
transitive dependency explicitly, and my list might easily get out of date. 
That is not much different from using wget and putting jars on the classpath.

If Maven resolved all the versions no matter how deep they were declared, then 
Maven could figure out the latest version, and it would avoid runtime failures.

 
{quote}Given this example is "oddly specific", I'd assume here some integration 
happens (DI container is expected at runtime), so yes, here you should either 
use "aligned libraries" (not always possible, especially if they are from 
multiple vendors) or then it is up to you to sort out the conflicts between 
them. Many many tools out there, ranging from Maven plugins to IDEs help you 
doing this.
{quote}
I am afraid I do not understand your suggestion here :(

Imagine the case is:
 * I'm the author of my-lib
 * my-lib does not use guice
 * my-lib uses both lib-a and lib-b which are third-party libraries, and I have 
no direct control over them
 * lib-a does not use guice
 * lib-b uses guice 5
 * Imagine my-lib declared dependencies in order of "lib-a, then lib-b", 
because, well, it was just fine

So far, so good. 

Then:
 * lib-a started using guice 3

Maven would cause runtime failures, because it would resolve guice 3, while 
lib-b required guice 5.

I do not understand why do you suggest resorting to third-party plugins and 
IDEs even for such a trivial case like library with a couple of transitive 
dependencies.

I understand that I can workaround the case by declaring guice version 
explicitly, however, I do not understand why Maven requires duplicating 
dependency information. If Maven discovered all the versions (guice 3 and guice 
5), then it could resolve the conflicts and come up with guice 5 on the 
classpath.

 
{quote} you mention "no such method" with protobuf-java, so I assumed Maven 
"wildly mixed" versions (like major ones), but to me it seems you talk about 
this issue{quote}

No. protobuf-java issue is not 11393, but it is like "Maven downgraded 
protobuf-java dependency, so the app failed".
Here's the error message: https://youtu.be/2kooPqDguyw?t=7087

In other words: sigstore-java used protobuf compiler 3.22, however, Maven 
resolved protobuf-java 3.21 for the runtime. It failed with the dreaded 
emptyList error leaving maven users no clue on the way to fix it.




{quote}Best would be to move this discussion to ML instead, preferably the 
users mailing list 

[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Tamas Cservenak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748113#comment-17748113
 ] 

Tamas Cservenak commented on MNG-7852:
--

For protobuf issue, here is a reproducer, a PR and example 
https://github.com/apache/maven/pull/1211

With this in place, you'd at least be warned that 2nd depMgt entry (for 
protobuf) is completely ignored as 1st depMgt import "deeply" had already 
imported it.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Tamas Cservenak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748094#comment-17748094
 ] 

Tamas Cservenak commented on MNG-7852:
--

And just FTR: you mention "no such method" with protobuf-java, so I assumed 
Maven "wildly mixed" versions (like major ones), but to me it sees you talk 
about this issue https://github.com/protocolbuffers/protobuf/issues/11393 that 
was simply a "bad release" happening between patch versions.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Tamas Cservenak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17748087#comment-17748087
 ] 

Tamas Cservenak commented on MNG-7852:
--

Maven provides solution to all your enlisted problems, but I still have hard 
time to grasp them...

1. you state "project does not use guava", then "but transitive may add guava" 
and then "user has no control which guava". As you (I guess) implied, this can 
be solved by multiple means, ideally by depMgmt. And yes, Maven makes you able 
to "not care", unlike Ant and others, where you need to enlist (and control) 
all the versions, with Maven you leave this to resolution. Or in other words, 
IF you care ("user has no control"), then use proper means like depMgt to sort 
out your issues.

2. Given this example is "oddly specific", I'd assume here some integration 
happens (DI container is expected at runtime), so yes, here you should either 
use "aligned libraries" (not always possible, especially if they are from 
multiple vendors) or then it is up to you to sort out the conflicts between 
them. Many many tools out there, ranging from Maven plugins to IDEs help you 
doing this.

3. This "real life example" is totally along the lines of Maven specd 
behaviour: the (deep) and over use of import scope, and the fact you had import 
for protobuf, but you simply was not aware that import above already imported 
it. Also, you should be aware that import "flattens" things, hence, if there 
would be no "overuse" of BOMs (meaning deep hierarchy), but let's assume you 
manually managed depMgt without BOM imports, you'd be immediately aware that 
you have TWO conflicting protobuf declarations in depMgt.

Best would be to move this discussion to ML instead, preferably the users 
mailing list https://maven.apache.org/mailing-lists.html

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which 

[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17747891#comment-17747891
 ] 

Vladimir Sitnikov commented on MNG-7852:


{quote}Am really unsure what you want to see as solution here
{quote}
It would really help me if you could suggest how Maven solves the issues in the 
description: 1, 2, 3.
The only workaround I can imagine for now is to re-declare all the dependencies 
manually, including the runtime dependencies of all the transitives. Of course, 
if dependencies are re-declared, they might get out of date, so it doesn't 
sound like a reasonable solution to me.

I suggest that Maven expand the complete dependency (regular dependency, and 
dependencyManagement) tree, and then perform conflict resolution. When dealing 
with conflict resolution, "newest wins" makes more sense than "oldest wins".
There's an option of "fail on conflict", however, it is not that practical.
Of course, it would be nice if Maven supported rich version constraints like 
"requires", "prefers", "rejects", "strictly", however, it is a different story.

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Vladimir Sitnikov (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17747888#comment-17747888
 ] 

Vladimir Sitnikov commented on MNG-7852:


{quote}all the rest of issues were closed as "works as expected".{quote}

Correct me if I am wrong, however, the only justification I saw was "works as 
expected since Maven uses nearest first algorithm".
I suggest reconsidering "nearest first" as it is not really manageable from the 
end-user point of view.

{quote} Maven never worked (unlike as npm) by "highest version" nor will.{quote}
Can you clarify why "highest wins" is not an option for Maven?

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)


[jira] [Commented] (MNG-7852) Use all the versions for dependency resolution rather than "nearest first" or "declared first"

2023-07-27 Thread Tamas Cservenak (Jira)


[ 
https://issues.apache.org/jira/browse/MNG-7852?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17747883#comment-17747883
 ] 

Tamas Cservenak commented on MNG-7852:
--

Aside of the "unexpected" (which is known issue, the runtime vs test scope), 
all the rest of issues were closed as "works as expected". Am really unsure 
what you want to see as solution here. Maven never worked (unlike as npm) by 
"highest version" nor will. It uses "dirty tree" (graph) to navigate, and uses 
properties like "distance" (from root) and "order" to make decisions, seems you 
argue against both.

What would you propose instead?

> Use all the versions for dependency resolution rather than "nearest first" or 
> "declared first"
> --
>
> Key: MNG-7852
> URL: https://issues.apache.org/jira/browse/MNG-7852
> Project: Maven
>  Issue Type: Improvement
>  Components: Dependencies
>Reporter: Vladimir Sitnikov
>Priority: Major
>
> Currently, Maven uses "nearest first", "declared first" rules for conflict 
> resolution: 
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> I suggest those rules are removed since they produce hard to reason 
> resolutions for transitive dependencies.
> Below I list reasons why both "nearest wins" and "declared first" yield 
> hard-to-predict behaviours, and they are likely to produce dependency 
> downgrades and the associated runtime errors.
> Here are some examples:
> 1) "Nearest first". Even though the rule sounds easy, it is not something the 
> users can control. For instance, if the project does not use Guava library, 
> some of the transitive dependencies could add a dependency on Guava. The user 
> has no control which dependency would be "the nearest" to declare Guava, so 
> user has literally no way to tell which Guava version will be used.
> The only workaround I see for the users is to declare Guava dependency 
> explicitly even though the project does not need it directly. It sounds like 
> Maven requires users to re-declare all the possible dependencies, including 
> the runtime-only ones.
> 2) "declared first". Of course, dependency order matters for classpath order, 
> however, it is not predictable in practice, and it might result in 
> downgrading dependencies. Imagine the project does not use Guice. However, 
> transitive dependencies might use Guice. At the same time, they might start 
> using Guice and stop using Guice, so the user can never tell which will be 
> the first project that uses Guice. Unfortunately, in Maven, the first project 
> that declares dependency wins, so  it might easily be the case that the first 
> mention of Guice will reference outdated version that would be incompatible 
> with the newer one required in another dependency.
> 3) Here's a real-life case: Maven downgrades protobuf-java dependency causing 
> something like NoSuchMethodError at the runtime. The step to reproduce is to 
> add dependency on dev.sigstore:sigstore-java:0.4.0. See [~hboutemy] analysis 
> in https://github.com/hboutemy/sigstore-maven-plugin/blob/import/analysis.md
> Long story short, sigstore-java does not depend on protobuf-java directly, 
> however, sigstore-java depends on several third-party libraries that 
> eventually depend on protobuf-java. Maven's "the first wins" behaviour 
> results in incoherent set of protobuf dependencies on the classpath.
> 4) see "unexpected" in MNG-5988
> To my best understanding, when it comes to transitive dependencies, both 
> "nearest first" and "declared first" are random variables which user can't 
> control unless they re-declare all the dependencies in their local pom. I 
> suggest Maven should not use random variables like "dependency depth" or 
> "dependency order" to drive conflict resolution.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)