Search code examples
javamavencompatibilitybackwards-compatibilitysemantic-versioning

Should I increase major version on dependency update


I'm aware that similiar questions have been asked before, but I specifically included the maven tag on this question for a reason. Scenario:

  • Project P has two dependencies, D1-1.2.3 and D2-2.0.0
  • D1-1.2.3 has D2-1.0.0 as a dependency
  • A class C in D1 uses (but does not expose) a class from D2 that has had a breaking change from version 1.0.0 to 2.0.0
  • P uses C

The maven dependency model dictates that since P's pom.xml explicitly states the D2 dependency, the version from the pom will be used. This causes P to break with a linkage error because of the incompatible change of the transitive dependency.

The semver FAQ states that this is a compatible change. It does say "since it does not affect the public API", yet with the scenario I outlined, every update to a dependency implicitly holds a risk of breaking consumers with linkage errors.

Should D1 increase major version? Is this bit of the semver specification simply not apt for maven projects because of its dependency model?


Solution

  • Whether the change is compatible or not, in this case, is entirely dependent on how the API consumer uses it, and this is beyond the responsibility of the API developer.

    As far as D1's developers are concerned, the public API remained unchanged, and, IMO, it's correct to state that it's not a breaking change.

    If the application using D1 also directly uses D2 because it happens to be a compile-scoped dependency, then this is completely the responsibility of the consumer. How? The consumer could anyway exclude the transitive dependency and replace it with a different version, and multiple consumers manage transitive dependencies differently.

    As you've stated, most of this is a result of how dependencies work in Maven or Java, but it is sensible to limit the responsibility of API developers to the public API.