Use-cases for version ranges?
Sangjin Lee
sjlee0 at gmail.com
Fri Nov 18 08:16:30 PST 2011
Fixed versions become problematic if your runtime consists of modules that
were not created by you and cannot be modified to coordinate their
versions. And that is a fairly common occurrence.
For example, suppose your module A depends on a third-part module B of
version 1.2.3 (and that only). But A also depends on another (unrelated)
third-party library module C of version 1.0.0. Furthermore, suppose C also
depends on B but of version 1.1.0 (and that only).
If we do not allow version ranges, this runtime would have to bring in both
versions of B into it. Depending on how B is used, this may lead to runtime
problems such as ClassCastExceptions. And this can quickly proliferate
especially if B is a popular library.
If you can modify C's module metadata to agree to whatever a common version
of B is, that would address this issue. However, that may not be always
doable or practical.
Version ranges are useful if there is actually room for different consumers
to agree on a common version of the provider. Yes, semantic versions play a
big part here, but IMO the alternatives are not as attractive.
BTW, the current JDK behavior can be considered as having a completely open
version range (0 to infinity). Once you're on the classpath, you're willing
(and forced) to accept any version. Using a fixed version is the other
extreme.
Regards,
Sangjin
On Fri, Nov 18, 2011 at 7:26 AM, Thomas Diesler <thomas.diesler at jboss.com>wrote:
> Yes OSGi uses a version scheme with semantic meaning (see the whitepaper
> on Semantic Versioning <http://www.osgi.org/wiki/**uploads/Links/**
> SemanticVersioning.pdf<http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf>>
> for details). This works very well as long as the world conforms to the
> semantic meaning of that scheme. In reality we see a wide vararity of
> versioning schemes being used - not all of them make sense let alone can be
> used to reason about compatibility.
>
> At jboss we use a model whereby the identity of a module is defined by
> 'identifier' plus 'slot'. A slot is not necessarily a version/range but a
> compatibility expression. The default slot is 'main' and would initially
> contain the version of the jar that you use to begin with
>
> org.log4j:main => log4j-1.2.14.jar
>
> Modules that have a dependency on log4j would use 'org.log4j:main' to
> express that. When there is an update to log4j, we can replace the binary
> in the same slot with the newer version as long as it is compatible (QA
> would check that). An incompatible version (e.g. log4j-2.0) can be
> installed on a new slot (e.g. 2x) and clients can be updated accordingly.
>
> Unlike OSGi, the dependency may be expressed within the deployment that
> has the dependency or externally as we do for all system components.
>
> OSGi requires that the unit of deployment is the 'bundle' for which it
> mandates that it uses semantic versioning mainly for its package
> import/exports.
>
> Bottom line: dependencies based on version ranges makes sense if there is
> a compatibility contract associated with version strings. (i.e. you must
> have some fidelity that 1.2 is backward compatible to 1.1 but 2.0 is not)
>
> -thomas
>
>
> On 11/18/2011 08:10 AM, Neil Bartlett wrote:
>
>> Suppose as the developer of module A, I declare a dependency on log4j,
>> exactly version 1.0.0 because I have not tested against log4j 1.0.1,
>> 1.0.2, 1.3, 999.999 etc. I effectively prevent my module *ever* being
>> used with log4j version 1.0.1 even if this combinations is later
>> tested and proven to work by somebody else. In other words, testing is
>> important but it doesn't necessarily have to always be done by the
>> original developer of each module.
>>
>> On the other hand let's say I state my dependency using the following
>> range: [1.2.14, 2.0). This is OSGi syntax and I believe Jigsaw is
>> following it, and it simply means I accept version 1.2.14 up to but
>> not including 2.0. Anybody can see that I compiled and tested against
>> 1.2.14, but has the option of using 1.2.15, 1.2.16, 1.3, 1.9 etc. It
>> does not mean that I *guarantee* my module will work with log4j 1.3
>> because that obviously depends on whether the log4j authors accept and
>> follow the common semantics of indicating backwards-incompatible
>> changes with a bump to the first version segment.
>>
>> The consequence of trying to lock down imports to a narrow range or
>> even a point version is that assembling an application becomes very
>> difficult, and we are forced to deploy many versions of common
>> libraries concurrently. This is non-optimal, though we can handle it
>> to some degree via per-module classloaders as in OSGi.
>>
>> Regards,
>> Neil
>>
>> On Thu, Nov 17, 2011 at 11:52 PM, cowwoc<cowwoc at bbs.darktech.org**>
>> wrote:
>>
>>> Can someone please explain why modules need to be able to specify version
>>> ranges for dependencies? I believe OSGI allows the specification of
>>> version
>>> ranges while Maven allows the specification of individual versions.
>>>
>>> The only thing that comes to mind is when module C depends on A and B, A
>>> depends on log4j 1.0, and B depends on log4j 1.1. What does C do? Is this
>>> the main use-case for version ranges?
>>>
>>> By the sound of it, this is a trust model where developers are told that
>>> log4j 1.x won't break compatibility so they depend on that range without
>>> actually testing against each version (newer versions may be released
>>> after
>>> their own software). I question whether such a mechanism is better or
>>> worse
>>> than depending on individual versions which may be overridden at a later
>>> time (a la Maven). On the one hand, you don't need to release a new
>>> version
>>> of the application each time a dependency is updated. On the other hand,
>>> no
>>> one is actually running tests to ensure that the versions are really
>>> compatible.
>>>
>>> Is there a way to get module A to see log4j 1.0 and module B to see log4j
>>> 1.1 (using separate ClassLoaders)?
>>>
>>> Thanks,
>>> Gili
>>>
>>> --
>>> View this message in context: http://jigsaw-dev.1059479.n5.**
>>> nabble.com/Use-cases-for-**version-ranges-**tp5002801p5002801.html<http://jigsaw-dev.1059479.n5.nabble.com/Use-cases-for-version-ranges-tp5002801p5002801.html>
>>> Sent from the jigsaw-dev mailing list archive at Nabble.com.
>>>
>>>
> --
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Thomas Diesler
> JBoss OSGi Lead
> JBoss, a division of Red Hat
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>
>
More information about the jigsaw-dev
mailing list