incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Version Policy
Date Mon, 09 Aug 2010 10:29:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Version+Policy">Version
Policy</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~fmeschbe">Felix
Meschberger</a>
    </h4>
        <br/>
                         <h4>Changes (31)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>{quote} <br></td></tr>
            <tr><td class="diff-changed-lines" >The exports in bundle/api/pom.xml
look like they might become problematic from a support point of view, although we probably
<span class="diff-changed-words">can<span class="diff-added-chars"style="background-color:
#dfd;">&#39;</span>t</span> avoid this. \[...\] \[The problem is the\]
manual maintenance of the version numbers. (not a big problem <span class="diff-changed-words">b<span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">i</span><span
class="diff-added-chars"style="background-color: #dfd;">u</span>t</span> needs
to be done) <br></td></tr>
            <tr><td class="diff-unchanged" >{quote} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >I agree, that this is a problem.
So <span class="diff-changed-words"><span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">L</span><span
class="diff-added-chars"style="background-color: #dfd;">l</span>et</span> me
reasonate on this a bit ;-) <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >As a reference you might want
to read [my <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">latest</span>
blog <span class="diff-changed-words">post<span class="diff-added-chars"style="background-color:
#dfd;"> on version numbers</span>|http://blog.meschberger.ch/2009/10/on-version-numbers.html]</span>
and also what the [Eclipse guys have to say|http://wiki.eclipse.org/index.php/Version_Numbering]
(great read, btw). <span class="diff-added-words"style="background-color: #dfd;">The
OSGi Alliance has come up with a good definition for [Semantic Versioning|http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf]
to which the definitions described below perfectly match.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">So
for Sling,</span> <span class="diff-added-words"style="background-color: #dfd;">For
Sling</span> we have three kinds of version numbers: <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" ># Big Sling <span class="diff-changed-words"><span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">r</span><span
class="diff-added-chars"style="background-color: #dfd;">R</span>eleases</span>
<br></td></tr>
            <tr><td class="diff-changed-lines" ># Sling <span class="diff-changed-words"><span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">b</span><span
class="diff-added-chars"style="background-color: #dfd;">B</span>undles</span>
<br></td></tr>
            <tr><td class="diff-changed-lines" ># Package <span class="diff-changed-words"><span
class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">e</span><span
class="diff-added-chars"style="background-color: #dfd;">E</span>xports</span>
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*Big
Sling Releases* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >For _Big Sling releases_ we <span
class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">have</span>
already <span class="diff-added-words"style="background-color: #dfd;">have</span>
an ample solution in that we just use a single number <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">which
is</span> increased from release to release. Just remember that a _Big Sling release_
is a convenience release of existing released Sling bundles. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">For
_Sling bundles_ version numbers are just defined as the {{&lt;version&gt;}} element
of the bundle&#39;s POM. The only restriction here is, that we decided to use even numbers
for releases and odd numbers for SNAPSHOTs. Whether and when which version part is increased
is not explicitly defined yet. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*Sling
Bundles* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">For
_Package exports_ the situation is more problematic since there are a number of places to
set exported package version number: In a {{packageinfo}} file inside the package (picked
up by the Maven Bundle Plugin to set the export version) or explicitly in the {{&lt;Export-Package&gt;}}
element of the Maven Bundle Plugin configuration or by reference to the bundle version number
using the {{$\{pom.version}}} variable. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">For
_Sling Bundles_ version numbers are just defined as the {{&lt;version&gt;}} element
of the bundle&#39;s POM. The only restriction here is, that we decided to use even numbers
for releases and odd numbers for SNAPSHOTs. Whether and when which version part is increased
is not explicitly defined yet. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Upto
now, we mostly used the {{$\{pom.version}} notation linking the exported package version to
the bundle version. This works well for bundles with simple exports. For more complicated
bundles, specifically for bundles with multiple exported packages which may evolve independently,
this does not work well. Additionally it also links the reasons for the bundle version changes
and the reasons for exported package versions. Finally, it increases the exported package
version without the package having any changes thus potentially confusing users. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*Package
Exports* <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">Consider
for example the Sling API bundle, which exports 7 packages. Each of which may evolve independently.
Now the {{resource}} package is extended causing a minor version increase. Should the version
numbers of the other exports also be increased ? Thus acting as if there was some API change
? <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">For
_Package Exports_ the situation is more problematic since there are a number of places to
set exported package version number: <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
 * In a {{packageinfo}} file inside the package (picked up by the Maven Bundle Plugin to set
the export version) <br>  * Explicitly in the {{&lt;Export-Package&gt;}} element
of the Maven Bundle Plugin configuration <br>  * By reference to the bundle version
number using the {{$\{pom.version}}} variable. <br> <br>Upto now, we mostly used
the {{$\{pom.version}} notation linking the exported package version to the bundle version.
Over time this mechanism leads to a number of problems: <br> <br>  * For bundles
with more than one package exported, the exported packages will evolve independently. As a
consequence their versionin should also evolve independently. An example of such a bundle
is the Sling API bundle of course. <br>  * Linking the package export version number
to the bundle version number confuses the actual semantics of both version numbers. The package
export version number only indicates the version of the actual package while the bundle version
number indicates a development state of the overall bundle. This will generally not be the
same. <br>  * The version of the exported package is increased on each bundle release,
even though nothing may have changed on the export. In such a situation the version of the
export should stay the same. <br> <br>That said, the reuse of the bundle version
as the package export version still is probably the correct thing to do for legacy library
wrappers. <br> <br>Consider for example the Sling API bundle, which exports 9
packages. Each of which may evolve independently. Now the {{resource}} package is extended
causing a minor version increase. Should the version numbers of the other exports also be
increased ? Thus acting as if there was some API change ? <br> <br></td></tr>
            <tr><td class="diff-unchanged" >I would say, no. Particularly if some
API implementation bundle is restricting the import version of the API implemented. Such an
implementation would immediately stop working because the version has been increased. But
since there has been no change, the implementation would still be correct. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This has not been discussed at large,
but I would assume, that the POM is still the correct place to take note of the version of
the exported packages. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*Future*
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The
newest versions of the BND library also support an {{@Export}} annotation in the {{package-info.java}}
pseudo class file. This pseudo class is supported starting with Java 5 to take package level
annotations (like the {{@Export}} annotation) and as a replacement of the {{package-info.html}}
file. <br> <br>Using this syntax something like the following would be easily
possible: <br> <br>{code} <br>/** <br> * This is the Package Level
JavaDoc <br> */ <br>@Export(version = &quot;1.0&quot;) <br>package
org.apache.sling.api.auth; <br>import aQute.bnd.annotation.Export; <br>{code}
<br> <br>See [Bnd Experimental|http://www.aqute.biz/Code/XBnd] for details. Unfortunately
the current Maven Bundle Plugin version does not support updating to the most recent BND library
versions due to incompatibilities. <br> <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. Version Number Syntax <br>
<br></td></tr>
            <tr><td class="diff-changed-lines" >As a small reminder, this is how
a version number is constructed:  In OSGi version numbers are composed of four (4) segments:
3 integers and a string <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">respectively</span>
named major.minor.micro.qualifier. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Each segment captures a
different intent: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >    * the minor segment indicates
_externally visible_ changes <br>    * the micro segment indicates bug fixes <br></td></tr>
            <tr><td class="diff-changed-lines" >* the qualifier segment is not
generally used but may be used to convey more information about a particular build, such as
a build time or <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">a</span>
<span class="diff-added-words"style="background-color: #dfd;">an</span> SVN revision
number. <br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This requires committers to think
well about changes they apply to exported packages: <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >* Removing interfaces, methods
or constants is likely an API breakage and thus requires a major version <span class="diff-changed-words">increase<span
class="diff-added-chars"style="background-color: #dfd;">. In Sling we try to prevent this
from happening.</span></span> <br></td></tr>
            <tr><td class="diff-unchanged" >  * Adding new methods to interfaces
is likely just an _externally visible_ change and thus requires a minor version increase <br>
 * Fixing a bug in an exported class just requires a minor version increase. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >JavaDoc updates generally do not
constitute a reason to evolve the version number. The exception is that if the JavaDoc update
is caused by a API limitation, it might be conceivable to increase the version number of the
exported package. A decision on this will <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">probably</span>
have to be taken on a case-by-case basis. <br></td></tr>
            <tr><td class="diff-unchanged" > <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h3. Pure API Bundle <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >An example of an almost _Pure
API Bundle_ is the Sling API bundle. This bundle exports <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">7</span>
<span class="diff-added-words"style="background-color: #dfd;">9</span> packages.
Some are really <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">quiet</span>
<span class="diff-added-words"style="background-color: #dfd;">stable</span> --
e.g. the {{org.apache.sling.api}} package or the {{org.apache.sling.wrappers}} package --
and some are being worked on at the moment -- e.g. the {{org.apache.sling.resource}} package.
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >To not break existing users of
the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">quiet</span>
<span class="diff-added-words"style="background-color: #dfd;">unmodified</span>
packages, the exported versions of these packages must not be increased. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>To signal to users of evolving
packages, that there might be new and interesting functionality, the version number must be
increased according to above definition. This also conveys to the implementor(s) of the API,
that they have to take some action. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h3. Implementation Bundle providing
API <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >An example of such a hybrid bundle
is the Sling Engine bundle. This bundle exports <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">three</span>
<span class="diff-added-words"style="background-color: #dfd;">two</span> packages
themselves defining API and contains a number of internal packages which actually implement
parts of the Sling API. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>A hypothetical evolution
of version numbers shown on one exported package and the bundle version might be as follows
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This default works well for consumers
of the API, since according to above definitions an API is guaranteed to not contain breakages
if the major version number is not increased. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >For bundles implementing the API,
this default does not work well, since from <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the
POV</span> <span class="diff-added-words"style="background-color: #dfd;">their
point of view</span> an _externally visible_ change in fact constitutes a breakage,
because the implementation is not complete. So if a bundle implements a package a manually
crafted import version should be defined which includes the export version of the defining
bundle but excludes the next minor version. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>For example implementing
the {{api}} package exported at version 1.2.3, would require the following manually created
{{Import-Package}} statement: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >This allows for the implementation
to work correctly with bug fixed package exports but as soon as there are any _externally
visible_ changes, the implementation bundle has to be adapted -- even if this just means increasing
the upper version bound in the {{Import-Package}} statement thus guaranteeing compliance (again).
<br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">*Future*
<br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Recent
versions of the BND library support automatic differntiation between use and implementation
of API and to set the import version ranges accordingly. See [Bnd Experimental|http://www.aqute.biz/Code/XBnd]
for details. Unfortunately the current Maven Bundle Plugin version does not support updating
to the most recent BND library versions due to incompatibilities. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h2. References <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >[On Version Numbers|http://blog.meschberger.ch/2009/10/on-version-numbers.html]
-- Blog about version numbers <br>[Version Numbering|http://wiki.eclipse.org/index.php/Version_Numbering]
-- An Eclipse paper on assigning version numbers. Very good read. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">[Semantic
Versioning|http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf] -- An OSGi Alliance
paper on semantic versioning. <br>[Bnd Experimental|http://www.aqute.biz/Code/XBnd]
-- Experimental extensions to the BND library; unfortunately these extensions are not yet
usable with Maven Bundle Plugin 2.1.0 due to API changes in the BND library not supported
by the plugin. <br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h1><a name="VersionPolicy-DRAFTVersionPolicy"></a>DRAFT Version
Policy</h1>

<p>This page is about how we assign versions to exported packages and bundles and defines
when to increase which part of the version number.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td>Please note that this
page is currently in draft stage and still being discussed.</td></tr></table></div>

<div>
<ul>
    <li><a href='#VersionPolicy-Introduction'>Introduction</a></li>
    <li><a href='#VersionPolicy-VersionNumberSyntax'>Version Number Syntax</a></li>
    <li><a href='#VersionPolicy-EvolutionofExportedPackageVersions'>Evolution
of Exported Package Versions</a></li>
    <li><a href='#VersionPolicy-EvolutionofBundleVersions'>Evolution of Bundle
Versions</a></li>
    <li><a href='#VersionPolicy-Examples'>Examples</a></li>
    <li><a href='#VersionPolicy-ImportingPackages'>Importing Packages</a></li>
    <li><a href='#VersionPolicy-References'>References</a></li>
</ul></div>

<h2><a name="VersionPolicy-Introduction"></a>Introduction</h2>

<p>In comments to SLING-1176 Ian Boston wrote:</p>

<blockquote>
<p>The exports in bundle/api/pom.xml look like they might become problematic from a
support point of view, although we probably can't avoid this. [...] [The problem is the] manual
maintenance of the version numbers. (not a big problem but needs to be done)</p></blockquote>

<p>I agree, that this is a problem. So let me reasonate on this a bit <img class="emoticon"
src="/confluence/images/icons/emoticons/wink.gif" height="20" width="20" align="absmiddle"
alt="" border="0"/></p>

<p>As a reference you might want to read <a href="http://blog.meschberger.ch/2009/10/on-version-numbers.html"
class="external-link" rel="nofollow">my blog post on version numbers</a> and also
what the <a href="http://wiki.eclipse.org/index.php/Version_Numbering" class="external-link"
rel="nofollow">Eclipse guys have to say</a> (great read, btw). The OSGi Alliance
has come up with a good definition for <a href="http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf"
class="external-link" rel="nofollow">Semantic Versioning</a> to which the definitions
described below perfectly match.</p>

<p>For Sling we have three kinds of version numbers:</p>

<ol>
	<li>Big Sling Releases</li>
	<li>Sling Bundles</li>
	<li>Package Exports</li>
</ol>


<p><b>Big Sling Releases</b></p>

<p>For <em>Big Sling releases</em> we already have an ample solution in
that we just use a single number increased from release to release. Just remember that a <em>Big
Sling release</em> is a convenience release of existing released Sling bundles.</p>

<p><b>Sling Bundles</b></p>

<p>For <em>Sling Bundles</em> version numbers are just defined as the <tt>&lt;version&gt;</tt>
element of the bundle's POM. The only restriction here is, that we decided to use even numbers
for releases and odd numbers for SNAPSHOTs. Whether and when which version part is increased
is not explicitly defined yet.</p>

<p><b>Package Exports</b></p>

<p>For <em>Package Exports</em> the situation is more problematic since
there are a number of places to set exported package version number:</p>

<ul>
	<li>In a <tt>packageinfo</tt> file inside the package (picked up by the
Maven Bundle Plugin to set the export version)</li>
	<li>Explicitly in the <tt>&lt;Export-Package&gt;</tt> element of
the Maven Bundle Plugin configuration</li>
	<li>By reference to the bundle version number using the <tt>${pom.version</tt>}
variable.</li>
</ul>


<p>Upto now, we mostly used the <tt>${pom.version</tt> notation linking
the exported package version to the bundle version. Over time this mechanism leads to a number
of problems:</p>

<ul>
	<li>For bundles with more than one package exported, the exported packages will evolve
independently. As a consequence their versionin should also evolve independently. An example
of such a bundle is the Sling API bundle of course.</li>
	<li>Linking the package export version number to the bundle version number confuses
the actual semantics of both version numbers. The package export version number only indicates
the version of the actual package while the bundle version number indicates a development
state of the overall bundle. This will generally not be the same.</li>
	<li>The version of the exported package is increased on each bundle release, even though
nothing may have changed on the export. In such a situation the version of the export should
stay the same.</li>
</ul>


<p>That said, the reuse of the bundle version as the package export version still is
probably the correct thing to do for legacy library wrappers.</p>

<p>Consider for example the Sling API bundle, which exports 9 packages. Each of which
may evolve independently. Now the <tt>resource</tt> package is extended causing
a minor version increase. Should the version numbers of the other exports also be increased
? Thus acting as if there was some API change ?</p>

<p>I would say, no. Particularly if some API implementation bundle is restricting the
import version of the API implemented. Such an implementation would immediately stop working
because the version has been increased. But since there has been no change, the implementation
would still be correct.</p>

<p>So, I think, we should evolve the exported package versions independently from each
other and even independently from the bundle version.</p>

<p>This places more burden on the developer when deciding on the exported package version
- in fact this requires such a decision as compared to have Maven take the decision by just
setting the bundle version.</p>

<p>The only problem is: Where shall this be noted ? In the POM or in the <tt>packageinfo</tt>
file ? If we would place the <tt>packageinfo</tt> file just beneath the class
source files, I would say, in the <tt>packageinfo</tt> file.</p>

<p>But this would require defining the class source locations as resource location in
the POM (at least for <tt>packageinfo</tt>) files.</p>

<p>I am not sure ....</p>

<p>This has not been discussed at large, but I would assume, that the POM is still the
correct place to take note of the version of the exported packages.</p>

<p><b>Future</b></p>

<p>The newest versions of the BND library also support an <tt>@Export</tt>
annotation in the <tt>package-info.java</tt> pseudo class file. This pseudo class
is supported starting with Java 5 to take package level annotations (like the <tt>@Export</tt>
annotation) and as a replacement of the <tt>package-info.html</tt> file.</p>

<p>Using this syntax something like the following would be easily possible:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
/**
 * This is the Package Level JavaDoc
 */
@Export(version = <span class="code-quote">"1.0"</span>)
<span class="code-keyword">package</span> org.apache.sling.api.auth;
<span class="code-keyword">import</span> aQute.bnd.annotation.Export;
</pre>
</div></div>

<p>See <a href="http://www.aqute.biz/Code/XBnd" class="external-link" rel="nofollow">Bnd
Experimental</a> for details. Unfortunately the current Maven Bundle Plugin version
does not support updating to the most recent BND library versions due to incompatibilities.</p>


<h2><a name="VersionPolicy-VersionNumberSyntax"></a>Version Number Syntax</h2>

<p>As a small reminder, this is how a version number is constructed:  In OSGi version
numbers are composed of four (4) segments: 3 integers and a string named major.minor.micro.qualifier.</p>

<p>Each segment captures a different intent:</p>

<ul>
	<li>the major segment indicates breakage in the API</li>
	<li>the minor segment indicates <em>externally visible</em> changes</li>
	<li>the micro segment indicates bug fixes</li>
	<li>the qualifier segment is not generally used but may be used to convey more information
about a particular build, such as a build time or an SVN revision number.</li>
</ul>



<h2><a name="VersionPolicy-EvolutionofExportedPackageVersions"></a>Evolution
of Exported Package Versions</h2>

<p>Version numbers of exported packages evolve independently from each other. Depending
on the changes applied, the micro, minor, or major segement is increased. Whenever the major
segment is increased, the minor and micro segments are reset to zero. Whenever the minor segment
is increased, the micro segment is reset to zero.</p>

<p>Segments are increased according to the above listing.</p>

<p>This requires committers to think well about changes they apply to exported packages:</p>

<ul>
	<li>Removing interfaces, methods or constants is likely an API breakage and thus requires
a major version increase. In Sling we try to prevent this from happening.</li>
	<li>Adding new methods to interfaces is likely just an <em>externally visible</em>
change and thus requires a minor version increase</li>
	<li>Fixing a bug in an exported class just requires a minor version increase.</li>
</ul>


<p>JavaDoc updates generally do not constitute a reason to evolve the version number.
The exception is that if the JavaDoc update is caused by a API limitation, it might be conceivable
to increase the version number of the exported package. A decision on this will have to be
taken on a case-by-case basis.</p>


<h2><a name="VersionPolicy-EvolutionofBundleVersions"></a>Evolution of Bundle
Versions</h2>

<p>Version numbers of bundles evolve depending on the evolution of the exported packages
but also depending on the evolution of the private code, which is not exported.</p>

<p>As a rule of thumb, the following reasons apply for increasing the segments of bundle
version numbers:</p>

<ul>
	<li>Increasing the major version number of any of the exported packages or restructuring
the bundle such that major parts are removed from the bundle (and either completely removed
or moved to other bundle(s)).</li>
	<li>Increasing the minor version number of any of the exported packages or refactoring
the internal code or implementing a package exported by another bundle whose minor (or even
major) version number has increased. Also functional extensions of the internal bundle classes
consitutes a reason to increase the minor version number.</li>
	<li>Increasing the micro version number of any of the exported packages or bug fixes.</li>
</ul>


<p>Note, that this definition does not require the bundle and epxorted package version
numbers to be synchronized in any way. While doing so might help in a first or second step,
over time it will become close to impossible to keep the versions in sync. So rather than
trying to keep the versions in sync, we should make sure, we increase the versions correctly.</p>


<h2><a name="VersionPolicy-Examples"></a>Examples</h2>


<h3><a name="VersionPolicy-PureAPIBundle"></a>Pure API Bundle</h3>

<p>An example of an almost <em>Pure API Bundle</em> is the Sling API bundle.
This bundle exports 9 packages. Some are really stable &#8211; e.g. the <tt>org.apache.sling.api</tt>
package or the <tt>org.apache.sling.wrappers</tt> package &#8211; and some
are being worked on at the moment &#8211; e.g. the <tt>org.apache.sling.resource</tt>
package.</p>

<p>To not break existing users of the unmodified packages, the exported versions of
these packages must not be increased.</p>

<p>To signal to users of evolving packages, that there might be new and interesting
functionality, the version number must be increased according to above definition. This also
conveys to the implementor(s) of the API, that they have to take some action.</p>


<p>A hypothetical evolution of version numbers shown on two packages and the bundle
version might be as follows</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> Description </td>
<td class='confluenceTd'> <tt>api</tt> package </td>
<td class='confluenceTd'> <tt>resource</tt> package </td>
<td class='confluenceTd'> bundle </td>
</tr>
<tr>
<td class='confluenceTd'> Initial Release </td>
<td class='confluenceTd'> 1.0.0 </td>
<td class='confluenceTd'> 1.0.0 </td>
<td class='confluenceTd'> 1.0.0 </td>
</tr>
<tr>
<td class='confluenceTd'> Bug fix in a <tt>resource</tt> class </td>
<td class='confluenceTd'> 1.0.0 </td>
<td class='confluenceTd'> 1.0.2 </td>
<td class='confluenceTd'> 1.0.2 </td>
</tr>
<tr>
<td class='confluenceTd'> New API in the <tt>resource</tt> package </td>
<td class='confluenceTd'> 1.0.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
</tr>
<tr>
<td class='confluenceTd'> New API in the <tt>api</tt> package </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.2.0 </td>
</tr>
<tr>
<td class='confluenceTd'> API breakage in the <tt>api</tt> package </td>
<td class='confluenceTd'> 2.0.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 2.0.0 </td>
</tr>
</tbody></table>
</div>



<h3><a name="VersionPolicy-ImplementationBundleprovidingAPI"></a>Implementation
Bundle providing API</h3>

<p>An example of such a hybrid bundle is the Sling Engine bundle. This bundle exports
two packages themselves defining API and contains a number of internal packages which actually
implement parts of the Sling API.</p>

<p>A hypothetical evolution of version numbers shown on one exported package and the
bundle version might be as follows</p>

<div class='table-wrap'>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> Description </td>
<td class='confluenceTd'> <tt>engine</tt> package </td>
<td class='confluenceTd'> bundle </td>
</tr>
<tr>
<td class='confluenceTd'> Initial Release </td>
<td class='confluenceTd'> 1.0.0 </td>
<td class='confluenceTd'> 1.0.0 </td>
</tr>
<tr>
<td class='confluenceTd'> Bug fix in a <tt>engine</tt> class </td>
<td class='confluenceTd'> 1.0.2 </td>
<td class='confluenceTd'> 1.0.2 </td>
</tr>
<tr>
<td class='confluenceTd'> Bug fix in an internal calss </td>
<td class='confluenceTd'> 1.0.2 </td>
<td class='confluenceTd'> 1.0.4 </td>
</tr>
<tr>
<td class='confluenceTd'> New API in the <tt>engine</tt> package </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
</tr>
<tr>
<td class='confluenceTd'> Implement new API from <tt>api</tt> 1.1.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.2.0 </td>
</tr>
<tr>
<td class='confluenceTd'> Refactor internal classes </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 1.3.0 </td>
</tr>
<tr>
<td class='confluenceTd'> Implement API from <tt>api</tt> 2.0.0 </td>
<td class='confluenceTd'> 1.1.0 </td>
<td class='confluenceTd'> 2.0.0 </td>
</tr>
</tbody></table>
</div>



<h3><a name="VersionPolicy-PureImplementationBundle"></a>Pure Implementation
Bundle</h3>

<p>For Pure Implementation Bundles only the bundle version numbers are maintained because
there is no exported package whose version number needs to be managed. This makes the decision
process of version number evolution very simple.</p>


<h2><a name="VersionPolicy-ImportingPackages"></a>Importing Packages</h2>


<p>When importing packages a version number will automatically be generated by the Maven
Bundle Plugin as follows:</p>

<ul>
	<li>If the providing package exports a package with an explicit version number, that
exact version number will be used as the lower bound</li>
	<li>If such a lower bound exists, the upper bound is exclusive the next major version
number.</li>
</ul>


<p>For example if importing the <tt>api</tt> package exported at version
1.2.3, the <tt>Import-Package</tt> statement is generated as</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Import-Package: api;version=[1.2.3,2.0.0)
</pre>
</div></div>


<p>This default works well for consumers of the API, since according to above definitions
an API is guaranteed to not contain breakages if the major version number is not increased.</p>

<p>For bundles implementing the API, this default does not work well, since from their
point of view an <em>externally visible</em> change in fact constitutes a breakage,
because the implementation is not complete. So if a bundle implements a package a manually
crafted import version should be defined which includes the export version of the defining
bundle but excludes the next minor version.</p>

<p>For example implementing the <tt>api</tt> package exported at version
1.2.3, would require the following manually created <tt>Import-Package</tt> statement:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Import-Package: api;version=[1.2.3,1.3.0)
</pre>
</div></div>

<p>This allows for the implementation to work correctly with bug fixed package exports
but as soon as there are any <em>externally visible</em> changes, the implementation
bundle has to be adapted &#8211; even if this just means increasing the upper version
bound in the <tt>Import-Package</tt> statement thus guaranteeing compliance (again).</p>

<p><b>Future</b></p>

<p>Recent versions of the BND library support automatic differntiation between use and
implementation of API and to set the import version ranges accordingly. See <a href="http://www.aqute.biz/Code/XBnd"
class="external-link" rel="nofollow">Bnd Experimental</a> for details. Unfortunately
the current Maven Bundle Plugin version does not support updating to the most recent BND library
versions due to incompatibilities.</p>

<h2><a name="VersionPolicy-References"></a>References</h2>

<p><a href="http://markmail.org/thread/zshobgjwtqrncajt" class="external-link" rel="nofollow">Version
Numbers</a> &#8211; The mail thread discussing version numbering<br/>
<a href="http://blog.meschberger.ch/2009/10/on-version-numbers.html" class="external-link"
rel="nofollow">On Version Numbers</a> &#8211; Blog about version numbers<br/>
<a href="http://wiki.eclipse.org/index.php/Version_Numbering" class="external-link" rel="nofollow">Version
Numbering</a> &#8211; An Eclipse paper on assigning version numbers. Very good read.<br/>
<a href="http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf" class="external-link"
rel="nofollow">Semantic Versioning</a> &#8211; An OSGi Alliance paper on semantic
versioning.<br/>
<a href="http://www.aqute.biz/Code/XBnd" class="external-link" rel="nofollow">Bnd Experimental</a>
&#8211; Experimental extensions to the BND library; unfortunately these extensions are
not yet usable with Maven Bundle Plugin 2.1.0 due to API changes in the BND library not supported
by the plugin.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Version+Policy">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=5965262&revisedVersion=8&originalVersion=7">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Version+Policy?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message