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 <http://java.io/>` 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> 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://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