I don’t know how broken version numbering is in general, but I would expect that a major version change normally indicates incompatibility, even if it doesn’t in this case. As such, I would expect any automated actions in the presence of such likely incompatibility would result in a selection of jars that just doesn’t work, and the only reasonable response I can think of is for maven to say “fix it yourself”.
What happens when there’s a minor version change in the jars? I think any attempt to solve this problem will re-invent OSGI. I’ve heard there are problems with it but I personally haven’t encountered them, other than no one being willing to understand and use it properly. David Jencks > On Oct 12, 2025, at 10:50 AM, Vladimir Sitnikov <[email protected]> > wrote: > >> 1. commons-compress 2 must not be compatible with v1 by commons rule (did >> we miss it? the rule is to change the package to "2") > > Romain, It sounds like you’re referring to an Apache Commons convention > (e.g., commons-lang -> commons-lang3, package rename to allow side-by-side). > > That can be useful for incompatible redesigns, but for a change like “keep > the same APIs, just split one JAR into multiple modules,” > forcing package renames places a significant burden on consumers. > > More broadly, preserving backward compatibility lets users upgrade without > code churn. > FWIW, semver.org does not require “v2 must be incompatible with v1” > >> 2. in your pom you can always exclude from a dep a transitive dep and > enforce it explicitly > > Could you please clarify with a concrete example? > If you mean adding exclusions everywhere and then adding an explicit > dependency on commons-compress, > that’s exactly the kind of manual fix I’m hoping to avoid. > > Here's the pom for the application: > https://github.com/vlsi/jarsplit/blob/5e3fa1ecd3f26a2116aa83a92e85b69560a597f6/lib-user-maven4/pom.xml > > Consider a novice user who depends on both lib-uses-v1 and lib-uses-v2. > Today Maven resolves commons-compress to 1.0.0, and they get a > NoSuchMethodError. > The recommended fix becomes: “exclude commons-compress (which you never > used directly) from multiple places > and then add it back explicitly at the top level; and later remember to > remove the workaround once transitive dependencies stabilize.” > > I think the build tool can do better than that. > > Here’s the kind of change I’m trying not to require users to hand-craft: > > --- a/lib-user-maven4/pom.xml > +++ b/lib-user-maven4/pom.xml > @@ -6,15 +6,32 @@ > <artifactId>app</artifactId> > <version>1.0.0</version> > <dependencies> > + <dependency> > + <groupId>org.example</groupId> > + <artifactId>commons-compress</artifactId> > + <version>2.0.0</version> > + </dependency> > <dependency> > <groupId>org.example</groupId> > <artifactId>lib-uses-v1</artifactId> > <version>1.0.0</version> > + <exclusions> > + <exclusion> > + <groupId>org.example</groupId> > + <artifactId>commons-compress</artifactId> > + </exclusion> > + </exclusions> > </dependency> > <dependency> > <groupId>org.example</groupId> > <artifactId>lib-uses-v2</artifactId> > <version>2.0.0</version> > + <exclusions> > + <exclusion> > + <groupId>org.example</groupId> > + <artifactId>commons-compress</artifactId> > + </exclusion> > + </exclusions> > </dependency> > </dependencies> > <build> > > This is brittle and requires users to know internal transitive details they > shouldn’t have to care about. > > Note: the app does not use commons-compress, nor does it know there's > commons-compress somewhere down the road. > > Yes, I could add a top-level dependencyManagement: > > <dependencyManagement> > <dependencies> > <dependency> > <groupId>org.example</groupId> > <artifactId>commons-compress</artifactId> > <version>2.0.0</version> > </dependency> > </dependencies> > </dependencyManagement> > > …but that’s precisely the point of my original request: the same > dependencyManagement already exists in commons-compress-core:2.0.0, > and I’d like Maven to honor it transitively so end users don’t need to > duplicate it in their root POMs > (which may not even “see” all the relevant transitive edges). > >> 3. if 2 is bothering the common trick is to do a module with packaging=pom >> doing the exclude+explicit dep and use this instead of the 3rd party > ... > > If by this you mean creating a wrapper module (a BOM or a “starter”) that > either (a) manages versions or (b) carries curated dependencies plus > exclusions, > then yes, that’s a known workaround. > It works, but it pushes complexity onto every consumer to adopt yet another > indirection layer. > > My goal is to avoid forcing all library users to create or adopt wrapper > modules just to get a safe, convergent outcome. > > I would much prefer Maven to honor the dependencyManagement present in > transitive POMs (e.g., commons-compress:2.0.0 managing its split modules). > That would let the ecosystem migrate from single-JAR to multi-JAR without > package renames and without end-user boilerplate > >> 4. maven enforcer or any other plugin to prevent > > the usage of v1 (or v2 aggregator module) anywhere > Enforcer is helpful for guardrails, agreed. I still want Maven to resolve > to 2.0.0 automatically in the simple case where an application depends > on two libraries that require different major lines of the same component. > > Enforcer can catch regressions; it shouldn’t be the primary mechanism to > coax Maven into a workable resolution. > > Vladimir --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
