First I’d like to thank everybody for their thoughtful responses. I’m sorry 
that this response was so long in coming. Unfortunately, the demands of my 
day-to-day, which is unrelated to anything OSGi, has taken quite a bit of my 
time lately.

I found all the responses very helpful but I must say that I found Peter’s 
response below to be extremely helpful especially the last two paragraphs. I do 
a few question have a specific example taken from the R7 OSGi Compendium spec 
that I still find confusing though.

Package org.osgi.service.transaction.control.jdbc provides two interfaces, 
JDBCConnectionProvider and JDBCConnectionProviderFactory.  The latter is 
@ProviderType as I’d expect but the former is @ConsumerType.  As a consumer of 
this API package, my expectation is that I won’t be implementing 
JDBCConnectionProvider but the API provider, Apache Aries for example, will be 
so that it should be @ProviderType instead of @ConsumerType since adding 
methods to this interface won’t impact me as a consumer.

Am I making any sense? Is it possible for an API to expose an @ConsumerType 
that isn’t implemented or extended by the consumer role? It would seem not. If 
that’s the case, is the primary reason the default is @ConsumerType (rather 
than @ProviderType) because it’s the more conservative choice, rather than the 
more common one because in my experience, the vast majority of types in an API 
are implemented by the provider rather than the consumer.

Thanks so much, I hope I’m not wasting anybody’s time here.

Scott

From: Peter Kriens <peter.kri...@aqute.biz>
Sent: Thursday, October 17, 2019 12:17 PM
To: Leschke, Scott <slesc...@medline.com>; OSGi Developer Mail List 
<osgi-dev@mail.osgi.org>
Subject: Re: [osgi-dev] @ConsumerType vs @ProviderType

It is surprisingly simple. :-)

Let's assume Oracle adds a new method to `java.nio.file.Path`. Would you care? 
Unless you work for Azul, you'd like couldn't give a rats ass. Once you use 
that new method you care, but before that moment it is irrelevant to you. That 
makes you a _consumer_ of the `java.nio.file` package. Azul and Oracle are, 
however, _providers_ of this package. Oracle and Azul do care when this method 
gets added because you would be very upset if the method is not there. However, 
if Oracle added a method to `java.io.Serializable` you would likely be pretty 
upset because you are a _consumer_ of the 
`java.io<https://urldefense.proofpoint.com/v2/url?u=http-3A__java.io&d=DwMFaQ&c=ZyuC0pi8BQ0JtN0UhY3DPMRPQOzp-0mvXzAggKz74wI&r=bjaNw_Ip6Cns5Gp3HC6K_oF-NLagO9fLr68IUFiG2XI&m=4j5tN615t0CCQkj0qKIfs7DsTPHcY6IZTKcyRWR3-x4&s=d1IEUgm1-X61sZi0T8Znk33Xo7ggGqLRmuWrUSlYF6k&e=>`
 package.

When you make a change to an API package you might break users of that package. 
To distinguish between the Azuls and Oracles of this world and mere mortals 
OSGi/bnd allows you to mark a type to be **only** affecting _providers_. I.e. 
the Path interface would be a _provider type_. (The @ConsumerType is default 
and just breaks everybody when you make a binary incompatible change.)

The archetypical example is Event Admin. If we add a method to the EventAmin 
interface we only break the 5 or 6 implementations of Event Admin. And we 
should break those implementation because they need to implement this new 
method. However, the 50 million bundles that depend on Event Admin are not 
affected since this change is fully backward compatible for them. However, if 
we add a method to Event Handler then we break all those 50 million bundles 
that implement Event Handler. That is why  the `EventHandler` interface is a 
@ConsumerType.

So the sole purpose of the @ProviderType annotation is to make a breaking 
change but indicate that only, the usually smaller number of, bundles that 
_provide_ the API should be broken instead of the majority of bundles that only 
_consume_ this API.

The key thing to realize is that provider/consumer is about the API **package** 
and not an interface. If you make a binary incompatible change, the key 
question is does it affect everybody (consumer and providers) or can I limit it 
to a smaller number of bundles (providers)?

PK

On 16 Oct 2019, at 21:15, Leschke, Scott via osgi-dev 
<osgi-dev@mail.osgi.org<mailto:osgi-dev@mail.osgi.org>> wrote:

I’m trying to wrap my head around these two annotations and I’m struggling a 
bit. Is the perspective of the provider and consumer roles from a bundle 
perspective or an application perspective?
I’ve read the Semantic Versioning whitepaper a number of times and it doesn’t 
really clear things up for me definitely.

If an application has an API bundle that only exposes Interfaces and Abstract 
classes, and those interfaces are implemented by other bundles in the app, are 
those bundles providers or consumers? My inclination is that they’re providers 
but then when does a bundle become a consumer?  Given that API bundles are 
compile only (this is the rule right?), would a good rule be that if you 
implement the interface and export the package it’s in, that type would be 
@ProviderType, if you don’t implement it it’s @ConsumeType?

It would seem to me that @ProviderType would be the default using this logic, 
as opposed to @ConsumerType, which leads me to believe that I’m thinking about 
this wrong.

Any help appreciated as always.

Regards,

Scott Leschke
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<mailto:osgi-dev@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev<https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.osgi.org_mailman_listinfo_osgi-2Ddev&d=DwMFaQ&c=ZyuC0pi8BQ0JtN0UhY3DPMRPQOzp-0mvXzAggKz74wI&r=bjaNw_Ip6Cns5Gp3HC6K_oF-NLagO9fLr68IUFiG2XI&m=4j5tN615t0CCQkj0qKIfs7DsTPHcY6IZTKcyRWR3-x4&s=oBOK5YFs59FcQQf9pSe_17TyLfgRykUb46b0ght36Yk&e=>

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

Reply via email to