Hi Phillip,

Phillip Hellewell wrote:

> Hi,
> 
> I need some advice on how to handle dependency compatibility issues.
> E.g., if A => B => C (and A => C directly too), my understanding is
> that Maven will allow me to update A to depend on a new version of C,
> even though B still depends on the old version.
> 
> But what if B is incompatible with the new version of C?
> 
> Here are some ways C might be changed:
> 1. An implementation change (e.g., a function in a .cpp file).
> 2. An interface change (e.g., class definition in a .h file).
> 3. A data structure change (e.g., a data member inside a class).

First: With a dependencyManagement section, you can overwrite the version od 
C used for A even if it is "only" a transitive version.

> #1 is the kind of change that usually doesn't cause any problems at
> all.  A can depend on a new version of C and that doesn't cause any
> problems for B.

The nice case.

> #2 is the kind of change that (hopefully) will cause a compile or
> linker error when building A.  If so, that's fine.  If not, this could
> be a serious problem.

At Apache commons we have meanwhile a consensus to change artifactId and 
package name, i.e. the next version of commons lang will be

org.apache.commons:commons-lang3:3.0

and the Java classes reside in package

org.apache.commons.lang3

This approach basically allows an older version to be used at the same time 
with the new one, but of course this is no longer a drop-in replacement.

For C++ this would mean changing the namespace and the artifactId.

However, the project maintaining a library must be aware of the problem and 
act accordingly. If they ignore the problem, their users are in trouble 
(happened in Java world e.g. for ASM 1.5.x to ASM 2.0 and a lot of stuff 
broke because).

> #3 is the kind of change that unfortunately will likely not manifest
> itself until the middle of runtime, probably with an unexpected
> crash!!

This again is in the responsibility of the project team to spot such things. 
In Java world we have tools like CLIRR that explicitly report binary 
incompatibilities and at Apache commons such changes are nor done for minor 
releases. The policy of the team has to be strict.

[snip]

> What is the best way to handle all this to avoid serious runtime
> issues?  One way I know of is to lock down versions with a range like
> [1.0.0.1].  But if my dependency tree is very tall, that means I may
> have to spend a lot of effort rebuilding many components when a
> low-level component changes.  Since most changes are
> implementation-only changes (#1), it would be nice to avoid that most
> of the time.

In combination with a dependencyManagement you can avoid version ranges at 
all, but it requires that the rules above are respected.

Maven cannot magically solve the compatibility problems that have been 
ignored by the teams, but it can help you to manage the versions if the 
teams act properly.

> Is it a common practice to solve this problem using version ranges
> such as [1.0.0-1.0.1), i.e., 1.0.0.x, and bump the 4th number for
> implementation-only changes, and bump the 3rd number for interface or
> other breaking changes?  But what if a programmer makes a breaking
> change and forgets to update the 3rd number, or they don't even
> realize that what they are changing constitutes as a breaking change?
> There's nothing you can do to prevent this, right?

It's always the same: Shit in ==> shit out :)

- Jörg


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@maven.apache.org
For additional commands, e-mail: users-h...@maven.apache.org

Reply via email to