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

Attachment: pgpBwD4wj7x6x.pgp
Description: OpenPGP digital signature

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

Reply via email to