Regardless, should the best practice for providing osgi.contract capabilities be to only provide one capability per osgi.contract name? And use Lists for attributes where you want to express multiple version support?
I know for a fact there are Servlet 2.5 applications that will simply break if run on a Servlet 3.0 implementation. If the best practice is to provide distinct osgi.contract capabilities for each 'version' then these types of user bundles will have issues binding to the correct contract. Tom From: BJ Hargrave/Austin/IBM@IBMUS To: osgi-dev@mail.osgi.org Date: 09/16/2016 10:08 AM Subject: Re: [osgi-dev] The JPA spec bundle does not work with jpa 2.1 Sent by: osgi-dev-boun...@mail.osgi.org As Tom mentions, when a bundle provides multiple contracts, the filter of the requirement only has to match one of the contracts. So adding an additional filter expression like (version<=2.1) does not exclude the bundle which also offers the contract at version=3. As an implementation bundle, contracts do not really help you. They were meant for using bundles: consumers of the API, not implementers of the API. The API bundle which provides the contract should probably export the packages with version(s) that the implemention bundle can import against to establish the tighter coupling between the API and the implementation. -- 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 5:16 PM 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
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev