I think we have opened an old discussion.  But I don't recall why things 
have ended up where they are with recommending multiple osgi.contract 
version capabilities from the same bundle that exports the packages.  So 
from https://www.osgi.org/portable-java-contract-definitions/ it states 
the following:

A bundle that provides servlet packages unversioned

Bundle-SymbolicName: JavaServlet30API
Bundle-Version: 3
Export-Package: javax.servlet, javax.servlet.http
Provide-Capability:
    osgi.contract;
       osgi.contract=JavaServlet;
       version:Version=3;
       uses:="javax.servlet, javax.servlet.http", 
    osgi.contract;
       osgi.contract=JavaServlet;
       version:Version=2.5;
       uses:="javax.servlet,javax.servlet.http"

So the suggestion is that an API bundle providing the JavaServlet contract 
at version 3.0 of the servlet spec would have two distinct exports of the 
servlet package.  One that has version 3 and one that has version 2.5. 
This becomes a real problem for a servlet container provider that 
implements the Servlet 2.5 specification.  They should use the following 
to import javax.servlet with contracts:

Bundle-SymbolicName: JavaServletImpl
Bundle-Version: 2
Import-Package: javax.servlet, javax.servlet.http
Require-Capability: 
    osgi.contract; 
        filter:="(&(osgi.contract=JavaServlet)(version=2.5))"

Now this becomes a real problem because there is NO WAY to prevent this 
JavaServletImpl from getting wired to the contract provided by the above 
JavaServletAPI which is actually exporting the javax.servlet packages from 
the Servlet 3.0 specification.  The reason is because the two 
osgi.contracts for JavaServlet are distinct capabilities and the framework 
is allowed to wiring JavaServletImpl to the lower versioned one which then 
constrains the JavaServletImpl to the exports of javax.servlet from 
JavaServlet30API.  The only way I can see this working is to have these 
API only bundles provide their supported versions in a single capability 
using a List<Version>:

Bundle-SymbolicName: JavaServletAPI
Bundle-Version: 3
Export-Package: javax.servlet, javax.servlet.http
Provide-Capability:
    osgi.contract;
       osgi.contract=JavaServlet;
       version:List<Version>="2.5,3";
       uses:="javax.servlet, javax.servlet.http", 

And for the JavaServletImpl to require the contract which excludes things 
higher or lower than what they implement:

Bundle-SymbolicName: JavaServletImpl
Bundle-Version: 2
Import-Package: javax.servlet, javax.servlet.http
Require-Capability: 
    osgi.contract; 
 filter:="(&(osgi.contract=JavaServlet)(version=2.5)(!(version>=2.5.1)))"

Notice the filter uses (version=2.5)(!(version>=2.5.1)) so that it will 
not  wire to something that provides one or more versions > 2.5.  There 
may be a better filter to exclude higher versions, but I ran out of time 
to think of one :)

But this does show the difficulty if the exporters of javax.servlet 
packages offer multiple osgi.contract capabilities for JavaServlet instead 
of a single one with a List<Version>

Tom





From:   Timothy Ward <tim.w...@paremus.com>
To:     OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Date:   09/15/2016 04:16 PM
Subject:        Re: [osgi-dev] The JPA spec bundle does not work with jpa 
2.1
Sent by:        osgi-dev-boun...@mail.osgi.org



BJ - My understanding is that contract versions don’t work like normal 
semantic versions (if only they did…) and that version 2.0.1 may be 
totally incompatible with version 2.0.0. I therefore don’t think it’s safe 
to use a range like “[2.1,2.2)”. My understanding of their intended use is 
that consumers select an exact version of the contract using “=“, and that 
providers declare the versions that they support. What I’m trying to do is 
to work out what providers and substitutable exporters should do.

To use a concrete example that actually exists.

If I write a Servlet 3.0 container, then I need to wire to the Servlet 3.0 
API. The Servlet 2.5 API will be missing interfaces that I need, causing 
NoClassDefFoundErrors, and the Servlet 3.1 API will have methods that I 
don’t implement, causing NoSuchMethodErrors if called at runtime.

I do, however, want the providers of the servlet packages to offer the 
servlet contract to consumers at backward compatible versions so that a 
Servlet 2.5 Servlet can be used on a Servlet 3.1 implementation. This is 
my understanding of why the contracts exist.

Therefore we have the following three API bundles, with contracts taken 
from https://www.osgi.org/portable-java-contract-definitions/

A (Servlet 2.5):

Export-Package: javax.servlet, javax.servlet.http
Provide-Capability: osgi.contract;
 osgi.contract=JavaServlet; version:Version=2.5; uses:="javax.servlet,
 javax.servlet.http"


B (Servlet 3.0):

Export-Package: javax.servlet, javax.servlet.http
Provide-Capability: osgi.contract; osgi.contract=JavaServlet; 
version:Version=3;
 uses:="javax.servlet, javax.servlet.http", osgi.contract;
 osgi.contract=JavaServlet; version:Version=2.5; uses:="javax.servlet,
 javax.servlet.http"

C (Servlet 3.1)

Export-Package: javax.servlet, javax.servlet.http
Provide-Capability: osgi.contract; osgi.contract=JavaServlet; 
version:Version=3.1;
 uses:=“javax.servlet, javax.servlet.http",
 osgi.contract; osgi.contract=JavaServlet; version:Version=3;
 uses:="javax.servlet, javax.servlet.http", osgi.contract;
 osgi.contract=JavaServlet; version:Version=2.5; uses:="javax.servlet,
 javax.servlet.http"


What imports/requirements should I put in my Servlet 3.0 implementation 
bundle to make it work? As a client I can use 
(&(osgi.contract=JavaServlet)(version=3.0)) to pick either B or C, but as 
a provider I need to match the exports from API Bundle B, and only bundle 
B. This is why I’m trying to further restrict the requirement to be “3.0 
or bust”, in an effort to exclude bundle C.

Regards,

Tim

On 15 Sep 2016, at 12:17, BJ Hargrave <hargr...@us.ibm.com> wrote:

But they are anded. So version=2.1 is the range[2.1,2.1]. This second 
range for version<=2.1 is [0,2.1]. So the intersection of those ranges is 
exactly 2.1. So the expression version<=2.1 adds no value.
 
If you want the range [2.1,2.2) then your filter expression is 
(&(version>=2.1)(!(version>=2.2)))
 
--

BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
hargr...@us.ibm.com
 
 
----- Original message -----
From: Timothy Ward <tim.w...@paremus.com>
Sent by: osgi-dev-boun...@mail.osgi.org
To: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Cc:
Subject: Re: [osgi-dev] The JPA spec bundle does not work with jpa 2.1
Date: Thu, Sep 15, 2016 2:58 PM
 
That was my intention. If I am a provider of version 2.1 of the JPA API 
then I need access to types defined in JPA 2.1, hence the (version=2.1). 
As a provider of the JPA API I also need to guarantee that I don’t wire to 
some future, backward-compatible version of the JPA API packages, as I 
won’t provide implementations for any new methods, hence adding 
(version<=2.1). 
 
I see this as the contract equivalent of a provider import range (e.g. 
“[1,1.1)”), whereas the typical consumer range (e.g. “[1,2)”) is handled 
as per David’s email. I do understand that this looks strange, but it’s 
the only way that I can see to have substitutability for this API, or to 
have the API delivered separately from the JPA provider implementation.
 
I appreciate any further insight that others may have!
 
Regards,
 
Tim
 
 
On 15 Sep 2016, at 11:47, BJ Hargrave <hargr...@us.ibm.com> wrote:
 
"(&(osgi.contract=JavaJPA)(version=2.1)(version<=2.1))" will only match 
exactly version 2.1 since the next term is anded.
 
 
--

BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
hargr...@us.ibm.com
 
 
----- Original message -----
From: Timothy Ward <tim.w...@paremus.com>
Sent by: osgi-dev-boun...@mail.osgi.org
To: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Cc:
Subject: Re: [osgi-dev] The JPA spec bundle does not work with jpa 2.1
Date: Thu, Sep 15, 2016 2:12 PM
 
Hi Christian,
 
Yes, this is a mess, and yes, it is hard. The JSR process has done a good 
job of making versioning as hard as possible!
 
For some extra help, bnd will do the contract import for your consumer if 
you use the -contract instruction (see 
http://bnd.bndtools.org/chapters/220-contracts.html). Contracts are the 
only reliable way for clients to deal with the inconsistent JSR versioning 
policies. 
 
I’m writing the following section because I know that Christian is also an 
implementor, and so needs to work out how to deal with the JPA provider 
side too. The information below is not needed by people who just want to 
use JPA in their applications.
 
Contracts work well for consuming the API in a client, but the requirement 
for providers that want substitutability (or just to use an external API 
bundle) is harder and I don’t think bnd helps much. To be substitutable 
you would need to write the contract so that you import the correct 
version, but not any version higher than that (otherwise clients may get 
NoSuchMethodErrors when trying to call API from higher versions. 
 
The following is my best guess at how to make the maximum number of things 
work!
 
The requirement filter looks very odd, and is expressed as follows 
(&(osgi.contract=JavaJPA)(version=2.1)(version<=2.1)):
 
For substitutable JPA 2.1 that works with current EclipseLink and 
Hibernate releases the metadata needs to be:
 
Export-Package:javax.persistence; javax.persistence.criteria; 
javax.persistence.metamodel; javax.persistence.spi;version=2.1.0;jpa=2.1
Import-Package: javax.persistence, javax.persistence.criteria, 
javax.persistence.metamodel, javax.persistence.spi
Require-Capability: 
osgi.contract;filter:=“(&(osgi.contract=JavaJPA)(version=2.1)(version<=2.1))”
Provide-Capability: 
osgi.contract:osgi.contract=JavaJPA;version:Version=2.1;uses:=“javax.persistence,javax.persistence.criteria,javax.persistence.metamodel,javax.persistence.spi”,
 
osgi.contract:osgi.contract=JavaJPA;version:Version=2.0;uses:=“javax.persistence,javax.persistence.criteria,javax.persistence.metamodel,javax.persistence.spi”,
 
osgi.contract:osgi.contract=JavaJPA;version:Version=1.0;uses:=“javax.persistence,javax.persistence.spi”
 
For substitutable JPA 2.0 that works with OpenJPA, and older EclipseLink 
and Hibernate releases:
 
Export-Package:javax.persistence; javax.persistence.criteria; 
javax.persistence.metamodel; javax.persistence.spi;version=2.0.0;jpa=2.0
Import-Package: javax.persistence, javax.persistence.criteria, 
javax.persistence.metamodel, javax.persistence.spi
Require-Capability: 
osgi.contract;filter:=“(&(osgi.contract=JavaJPA)(version=2.0)(version<=2.0))”
Provide-Capability: 
osgi.contract:osgi.contract=JavaJPA;version:Version=2.0;uses:=“javax.persistence,javax.persistence.criteria,javax.persistence.metamodel,javax.persistence.spi”,
 
osgi.contract:osgi.contract=JavaJPA;version:Version=1.0;uses:=“javax.persistence,javax.persistence.spi”
 
This is what Aries JPA and Transaction Control need to do when providing 
the JPA API, and it will be described in the upcoming JPA Service update. 
 
Note that all of this will probably still not help with JPA providers that 
have even crazier import ranges, but we do what we can.
 
Regards,
 
Tim
 
 
On 15 Sep 2016, at 05:15, David Bosschaert <david.bosscha...@gmail.com> 
wrote:
 
Hi Christian, 
 
The portable contracts define how you should do your imports with 
JSR-based APIs, since they often don't follow semantic versioning. What 
should really be done is:
 
Import-Package: javax.persistence, javax.persistence.criteria, 
javax.persistence.metamodel, javax.persistence.spi
Require-Capability: osgi.contract; 
filter:="(&(osgi.contract=JavaJPA)(version=2.1))"
 
Note that the Import-Package in this case has no version associated with 
the packages. This is because there is no agreed semantic versioning 
associated with these packages. So providers of the JPA package can 
version these using whatever schema they want. 
Consumers bind to the specific version of JPA via the Require-Capability 
which specifies the exact version needed (not a range). Implementations 
list all the version numbers of the JSR-spec that they are compatible 
with. For more info see [1] and [2].
 
Obviously this only works when the OSGi-JPA provider implementation 
supports osgi.contract by providing the JavaJPA capability for all the 
versions that it is compatible with (1, 2 and 2.1). For older OSGi-JPA 
implementations this may not be the case as it may be that they predate 
the osgi.contract namespace...
 
Best regards,
 
David
 
[1] http://blog.osgi.org/2014/09/portable-java-contracts-for-javax.html
[2] https://www.osgi.org/portable-java-contract-definitions/
 
 
On 15 September 2016 at 12:31, Christian Schneider <
ch...@die-schneider.net> wrote: 
Unfortunately the spec only defines the jpa package properties up to jpa 
2.0. Do the OSGi specs already define JPA 2.1 somewhere?

I just checked some of the JPA API bundles and they provide very different 
package versions.

org.eclipse.persistence:javax.persistence:2.1.0 has 
javax.persistence;jpa="2.1";version="2.1.0"

org.apache.geronimo.specs:geronimo-jpa_2.1_spec:1.0-alpha-1 has 
javax.persistence;jpa="2.1";version="1.2"

Which of these is correct?

How would a client correctly express the dependency to the jpa 2.0 or 2.1 
API?
I see that there is also jpa=2.1 on the package export. Can the be used to 
describe the import?

Currently I use a version range of [2.1,2.2) in my own code. Not sure if 
this is correct.

I think it would also make sense to recommend specific maven coordinates 
for each persistence spec as a kind of offical spec bundle to use. Elese 
people might choose the wrong and end up with broken imports.

Christian

On 08.07.2016 15:41, Christian Schneider wrote: 
Done
https://osgi.org/bugzilla/show_bug.cgi?id=189

Christian

On 08.07.2016 14:49, Raymond Auge wrote: 
Christian could you file a bug on the public OSGi bugzilla so we don't 
forget to fix this?

I wonder if the spec bundle should refer to javax.persistence via Portable 
Java Contract rather then by package version. We have a similar issue with 
the org.osgi.service.http bundle which I believe should also refer to a 
PJC for javax.servlet.

https://osgi.org/bugzilla/buglist.cgi

- Ray
 

 
--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
 

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
 

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev



_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to