Hi Mark, > On 22 Jul 2017, at 14:23, Mark Raynsford <list+org.o...@io7m.com> wrote: > > 'Ello. > > I suspect we're in agreement, but I think there may've been a slight > miscommunication somewhere... > > On 2017-07-22T12:39:41 +0100 > Neil Bartlett <njbartl...@gmail.com> wrote: >> >> 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. > > Yes, as am I. I used the example of multiple versions of the same jar > resulting in multiple conflicting registrations of services trying to > use the same name because having multiple versions of the same jar is > the primary "error" case where this can happen. If we ignore the case > where two unrelated jars or bundles publish services that just happen > to pick conflicting names, then that just leaves us with the case where > two versions of the *same* jar attempt to publish services with > conflicting names.
But why ignore that case? It’s the primary problem. As you said, the case of having multiple versions of the same module already has some protections around it — in fact it’s only really possible in OSGi. The fundamental problem, it seems to be, is that you simply cannot *stop* two or more people providers from saying, “hey I have an ImageFormatter for PNG files”. That is true under Java <9 without OSGi, it’s true under OSGi, and it’s true in Java 9, so all of those things seem to be distractors. > > So, with that in mind: In Java < 9, having multiple versions of the > same jar on the classpath is discouraged and considered to be bad > practice, so this situation is _possible_ but _somewhat less likely_ to > occur with ServiceLoader. In Java 9, there are VM-level checks in place > to prevent conflicting modular jars from being loaded, so this > particular error case can't happen. In OSGi however, as I said, it's > possible if not encouraged to have two different versions of a bundle > installed, so this error case *can* occur. That's not a disadvantage of > OSGi at all, quite the opposite, but it does mean that classes that do > that kind of centralized registration of services have to be able to > cope with it. I don’t know what kind of VM-level checks you’re talking about here, and as one of the experts on the JSR 376 Expert Group, I suppose that I really should know. You may be confused with the multiple export restriction? Which says you can’t have multiple modules exporting the same package in the same JPMS Layer. However that’s not relevant because a service provider doesn’t need to export anything at all. There only needs to be one export of the service API package — that is, the ImageFormatter interface. All of the providers simply import that package and implement the interface. Obviously in Java you can have multiple implementations of an interface. > >> 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. > > Again, I agree. However, I gave the example of the ImageIO interface as > a general example of a problem: You have multiple providers, those > providers are essentially hidden from you, and you only have a > mindlessly simple selection criteria such as "PNG" to pick a provider. > Under traditional Java, the problem is slightly diminished in some > sense because of the primitive nature of ServiceLoader, the > generally static nature of module deployments, and in Java 9, the > VM-level ModuleLayer checks. Under OSGi, the situation is more complex, > and I was asking how experienced OSGi people tended to deal with the > situation. Nothing more! I think you may also be touching on the philosophical difference between a service and a library in OSGi. With a service, you just want an implementation of an interface and — though you can influence the choice to some extent — you don’t ultimately care which implementation you get. This has the huge advantage of decoupling consumers from providers but it does occasionally leave you in the situation of needing to arbitrarily choose between multiple providers that seem to be equally valid. But that’s okay because… remember… you don’t care which implementation you get. In the case of a library, you directly instantiate a particularly class because you really need that particular implementation. For example when you create a Base64Encoder you really don’t want OSGi or anybody else to substitute a different encoding! This requires coupling to a concrete class but it guarantees you always get exactly what you want. There are some degrees of grey between these opposites, such as when you request an ImageFormatter with a specific name, or a MigestDigest with a specific algorithm, etc. Neil > > -- > Mark Raynsford | http://www.io7m.com _______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev