Hi, The normal strategy here would be to give priority to the ImageFormat service with the highest *service-ranking* and ignore others with the same name. Depending on how you set up your ImageFormats class you can even have DS inject services in ranking order to make it easier. Anyway there are better sources than me to explain it once you know what to search for so I'll leave it at that.
As for multiple versions of the same bundle providing the same service, well they would probably share the same service-ranking so that's no longer a solution ... but then you have to wonder about the design choices which might allow this situation to happen. Typically if you have to deploy multiple versions of the same service provider, it's because they are implementing different versions of an API. In other words, you may have some bundles consuming e.g. the image format 1.0.0 API and others consuming the image format 2.0.0 API, such that you need to deploy a PNG ImageFormat service implementing each one. In this case they're not actually going to mix, as you will also need two respective versions of the ImageFormats component which will pick them up separately. Sure, it's possible to imagine a situation where the two PNG ImageFormat services would both need to be deployed even though they implement the *same* API version, but if this is actually happening it almost certainly should have been avoided. Perhaps by having a cleaner versioning strategy and not over-burdening the bundle which provides the PNG ImageFormat service with too many independent responsibilities. On Fri, 21 Jul 2017 at 19:26 Mark Raynsford <list+org.o...@io7m.com> wrote: > Hello. > > Consider an API like ImageIO. To write an image in the PNG format, one > calls: > > ImageIO.write(image, "PNG", output); > > The implementation of the write() method gets a list of the available > formats via ServiceLoader and picks the one named "PNG". The "PNG" > value is the sole criteria used to pick an image format provider. > > In OSGi, we'd use the whiteboard pattern (probably with declarative > services) to implement this. The implementation might look something > like: > > interface ImageFormat > { > String name(); > ... > } > > @Component > public final class ImageFormats > { > private final ConcurrentHashMap<String, ImageFormat> formats = > new ConcurrentHashMap<String, ImageFormat>(); > > @Reference( > cardinality = ReferenceCardinality.MULTIPLE, > policy = ReferencePolicy.DYNAMIC, > unbind = "onFormatUnregister") > public void onFormatRegister( > final ImageFormat format) > { > this.formats.put(format.name(), format); > } > > public void onFormatUnregister( > final ImageFormat format) > { > this.formats.remove(format.name(), format); > } > > ... > } > > This would work perfectly well, but what happens if two bundles > try to register a format with the same name? We could check for > and reject registrations with overlapping names, but that might > leave developers/users stuck with a format implementation that > they don't like. What if two different versions of the same bundle > are installed, and both try to register themselves? > > This is a problem that seems to come up in various guises each > time I work with OSGi, and I've not really seen a satisfactory > solution to it. Many solutions involve bubbling up the entirely > internal concern of there being multiple versions of a format > provider present to the API, and although this can work, it does > mean that users are then forced to intelligently pick providers > ("I just want PNG, why do I have to care which of the providers > I end up with?! Isn't the ImageFormats class supposed to pick > for me?!"). Part of this problem is caused by the fact that the > ImageFormats class exists at all; users could, for example, > search for services providing ImageFormat themselves via DS or > the OSGi APIs. Sometimes, though, a class analogous to ImageFormats > is necessary, particularly when you expect callers to be OSGi-unaware > and/or you only have very simple selection criteria (like a "PNG" > string). > > How do people that know more about OSGi than I do usually handle > this? > > -- > Mark Raynsford | http://www.io7m.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