I'm not talking at all about multiple versions of the same jar. I'm talking about multiple providers of the same service, possibly even from different vendors. This happens just as easily under Service Loader as under OSGi.
In your original email you asked: why does the consumer of PNG have to care which PNG provider to choose. Well isn't that just a fact of life? I need a plumber to fix my toilet... there are ten plumbers in my town, which should I choose? Why do I have to care about plumbers?! Having choices can suck, but not as much as having no choice. Neil On 22 Jul 2017 10:44 am, "Mark Raynsford" <list+org.o...@io7m.com> wrote: > On 2017-07-22T00:22:31 +0100 > Neil Bartlett <njbartl...@gmail.com> wrote: > > > Hello Mark, > > 'Ello. > > > > > Tell me, why is this problem any harder under OSGi than with > ServiceLoader?? In both cases, anybody can install a bundle or a JAR that > provides a service with a name, and those names can collide. > > In Java < 9, it's not so much that it can't happen, but more that > having two different versions of the same jar file on the classpath is > considered a mistake, and build tools like Maven will (via the Enforcer > plugin) try to prevent that from happening. In Java 9, it's explicitly > an error for two modular jars in the same ModuleLayer to export the > same package, so the program won't even start up if you try it. In > OSGi, having multiple versions of a bundle installed and running is not > considered an error (although it's probably not exactly encouraged > either), so the hypothetical ImageFormats class that tracks providers > by name would give inconsistent results in that situation. > > > In both ServiceLoader and OSGi there is a simple rule for selecting a > single instance of a service where many are available. Under ServiceLoader > it is just the first JAR on the classpath. With OSGi you can attach a > service.ranking property to any service. This can be done by the developer > of the service, or supplied/overridden at runtime using Config Admin. Note > that even with service.ranking, it is possible to have multiple service > with the same high ranking. In this case OSGi picks the service with the > lowest service.id, which in effect usually means the one that was > registered first. > > Yes, I'm aware. As I mentioned in the other message to this list, using > the service ranking and ID would *probably* be fine given a very > long-running framework instance, because the ordering of service.id will > most likely reflect the order in which a given set of bundle versions > were installed. However, if you start up a new framework instance with > a set of bundles already in the bundle cache, there's nothing that > guarantees that the older bundle versions will get lower service IDs, > right? > > > By the way it is generally bad practice to provide a service name via a > method on the service interface. Better to add this as a property to the > service metadata, so that it can be selected using declarative filters. For > example: > > > > @Component(property = “name=JPEG”) > > public class JPEGImageFormat implements ImageFormat { … } > > > > @Component > > public class PaintProgram { > > @Reference(target = “(name=JPEG)”) > > ImageFormat formatter; > > // ... > > } > > I'd tend to agree, but I did make this point: > > > 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). > > In other words, if you're writing code that is expected to work both > when running in an OSGi framework and when running on the classpath or > module path, you may want/need to abstract over the registration of > ImageFormats. In other words, you might want to provide a hypothetical > ImageFormatRegistry interface that _both OSGi and non-OSGi consumers_ > can make calls into to find image formats (to avoid having to write > one code path for OSGi, and one code path for everyone else). Outside of > OSGi, the best-practice rules for Java < 9 make multiple registrations > of an ImageFormat less likely. The strict Java 9 rules regarding > conflicting package exports make multiple registrations impossible, at > least when those registrations come from two different versions of the > same modular jar. In an OSGi framework, however, the situation is > slightly more permissive than the Java < 9 case; multiple installed > versions of a bundle are a reality, and complicate the implementation of > ImageFormatRegistry class. > > -- > Mark Raynsford | http://www.io7m.com >
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev