This is another reason why you should keep APIs separate from implementations. While there is often a need to go back and change an old version of an implementation package, APIs should really only ever move forwards. For example if you really need to delete a method that you added in version 1.1, then you probably need to move to 2.0 (since deleting methods is a breaking change for both providers and consumers).
With respect to tooling, bnd and Bndtools offer a lot of functionality for getting semantic versioning correct. In v2.0 we have a "Release to Repository" tool that compares the current version of an API against the previous release and tells you what the version should be, based on the API differences. We can also generate errors to break the build if a change is made to an API without reflecting that change through the package version. Finally, consumers and providers of the API are automatically given the correct import range (e.g. [1.0,2.0) for a consumer versus [1.0,1.1) for a provider). I believe that through consistent use of these tools you should never get incompatibility problems such as NoSuchMethodError. Neil On Mon, Jan 28, 2013 at 8:22 PM, Henning Andersen <[email protected]>wrote: > Thanks for your comments. I agree that option 1 is the technically best > option. Unfortunately, it is very likely that at some point in the future, > we will be forced into extending an API in an old version/branch anyway. > > You write that if it is necessary, we should add it in the main branch > first and then backport to maintenance branch(es) afterwards. Is there a > best practice for how to handle the version numbering of exports and > imports (safely) for such a backport? Or any tools available that can help? > I worry that if we have to manually handle the fact that a build of a > bundle is compatible or incompatible to other bundles manually, we risk > errors resulting in method-not-found exceptions etc. > > Regards, > > Henning > > > > > On Fri, Jan 25, 2013 at 4:16 PM, BJ Hargrave <[email protected]> wrote: > >> Option 1 is your best choice. API packages need careful, long term >> architecture. They are the contract of your bundle. Adding such fixes in a >> maint branch is dangerous as the package diverges over your branches. If >> this is necessary, you need to fix first in the main branch and, when >> happy, consider backporting to the maint branch(es). You need a linear >> history of the package evolution. >> >> -- >> >> *BJ Hargrave* >> Senior Technical Staff Member, IBM >> OSGi Fellow and CTO of the *OSGi Alliance* <http://www.osgi.org/>* >> **[email protected]* <[email protected]> >> >> office: +1 386 848 1781 >> mobile: +1 386 848 3788 >> >> >> >> >> >> >> From: Henning Andersen <[email protected]> >> To: [email protected], >> Date: 2013/01/25 10:02 >> Subject: [osgi-dev] Fwd: Branching, versioning and API changes >> Sent by: [email protected] >> ------------------------------ >> >> >> >> Hi OSGi developers, >> >> we have been using OSGi for 3 years now, however without semantic >> versioning. We now want to take our versioning strategy to the next level >> by introducing semantic versioning and allowing individual release cycles >> for different components in our system. >> >> One of the issues we are struggling with is how to handle branches and >> versioning, especially in relation to API changes. >> >> Consider a package p with a single class C, with a single method m: >> >> package p; >> >> public class C { >> public void m(); >> } >> >> Now say, we released a bundle B in version 1.0, with this package in >> version 1.0. To allow us to bug fix, the bundle B is branched into a 1.0 >> branch too in our source code repository. >> >> Another bundle X has Import-Package: p; version="[1.0;2)" as per semantic >> versioning and is released as version 1.0. >> >> Development of class C continues and a new method is added: >> >> public class C { >> public void m(); >> public void n(); >> } >> >> This is released in a new version of B, bundle-version 1.1, package >> version 1.1. >> >> Now a customer has X 1.0 and B 1.0. They request a new feature to X, but >> reject to upgrade B. The feature in X requires an API extension to the >> class C. So we add this in the 1.0 branch: >> >> public class C { >> public void m(); >> public void o(); >> } >> >> If we were to follow semantic versioning, we should release this as B >> version 1.1, p version 1.1. However, these numbers are already occupied. >> >> So we have to break the principle and release them as B version 1.0.1 and >> p version 1.0.1. >> >> The developer of X now needs to import the package p in the right >> version. However, using: Import-Package: p; version="[1.0.1;2)" is not >> entirely right, since his code is not compatible with the 1.1 version. >> >> So far we have 5 solutions: >> >> 1. Do not allow it. Only allow extending the API in a new minor version >> following the latest released version. >> 2. Add an attribute to the export 'Export-Package: a; version=1.0.1; >> p.C.o = true' and do the same on 'Import-Package: a; version="[1.0.1,2)"; >> p.C.o = true'. Requires that we identify the dependency to method level. >> 3. Fix the version of a in X: 'Import-Package: a; version="[1.0.1,1.1)"'. >> This however has the implication that X need upgrade when we upgrade B. >> 4. Build two bundles out of X, one with 'Import-Package: a; >> version="[1.0.1,1.1)"' and one with 'Import-Package: a; >> version="[1.1.1,2)"' (assuming the method was also added in 1.1.1). >> 5. Branch X into two versions (much like 3), with different import >> versions >> >> We think some of these could work, but do wonder if others have run into >> the same issues or similar branching/versioning issues and how they solved >> it? Any input is highly appreciated. >> >> Thanks, >> >> Henning >> >> _______________________________________________ >> OSGi Developer Mail List >> [email protected] >> https://mail.osgi.org/mailman/listinfo/osgi-dev >> >> >> _______________________________________________ >> OSGi Developer Mail List >> [email protected] >> https://mail.osgi.org/mailman/listinfo/osgi-dev >> > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev >
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
