Hi David,

Honeslty, I'm to be blamed for these mechanisms :-). They were introduced in the huge patch attached to ARIES-373. I thought that the fact that you applied this patch means that you had approved those changes ;-).

More seriously, I agree that this approach is complex and has lots of drawbacks. The main issue is that there is no well-defined mapping between service ids and these human readable API names that are used as a name of the path element inside the header. This causes some weird strategies to looking up implementations to be used on the SPI consumer side.

The approach that we're now discussing was just a proposal, but let me explain why I introduced this. There are two main reasons:

1) Some APIs load more than one file with SPI configuration. In other words, they use many SPI (or SPI-like) service ids. Javamail is a good example of such an API. If we drop these human readable path element names and service id is used instead, we would need to add many path elements for a single implementation of a given API.

2) Human readable names let us hide all those complex service ids inside the SPI provider bundles. The number of SPI providers will be relatively small, so it's not a problem to expose the complexity of SPI Fly to people that create (bundle) those. However, the number of bundles that are SPI consumers will be much, much greater.
I think that being forced to add a header like
SPI-Consumer: javamail.default.providers;name="sun"
to your bundle once you need to use a specific impl version might cause people to abandon using SPI-Fly and try something more straightforward (i.e. rebundled APIs shipped with ServiceMix).

As I said, each approach has some pros and cons. We just need decide which approach has least significant disadvantages.

One more thing: I think that the approach with SPI-Provider header without any contents might be too simplistic. It will force us to either drop the feature that enables SPI consumers to specify the name of the preferred implementation or create some rules for generating implementation name for the given SPI provider on the basis of bundle name and bundle version.

Best regards,
  Bartek

David Bosschaert wrote the following on 11/3/2010 5:33 PM:
Hi all,

I'm currently looking at the SPI-Fly component again and rationalizing
the SPI-Provider header. Currently the SPI-Provider header in the code
base has two required attributes: provider-name and service-ids.

In the code I found the following comment:
// Format of each path element:
// api1Name;provider-name="myimpl2";service-ids="myserviceId"

// An example below.
// Please note:
// 1. The service-ids attribute holds a list of ids that will be
// used when searching META-INF/services/. In other words
// this will be the name of the class that will be passed to
// ServiceLoader.load().
// 2. A single bundle can provide implementations for many APIs
// - there might be many api names in a single SPI-Provider
// header.

// Sample:
// jaxb;provider-name="xerces123";service-ids="javax.xml.bind.JAXBContext"

I'm a little puzzled by this. I can see that provider-name could be
useful in that it would be an additional service property. In the
sample above, what would the relation between service-ids and the
initial 'jaxb' piece? Should it not be something like
SPI-Provider: javax.xml.bind.JAXBContext;provider-name="xerces123" ?
besides, JAXB is probably a bad example because JAXB doesn't follow
the common pattern in that the files in
META-INF/services/javax.xml.bind.JAXBContext don't list
subclasses/implementations of JAXBContext.

So anyway. I don't understand the function of 'service-ids' and I
think that provider-name should be an optional attribute.
So you could have the following headers (examples):
SPI-Provider: javax.xml.parsers.DocumentBuilderFactory
SPI-Provider:
javax.xml.parsers.DocumentBuilderFactory;provider-name="Xerces 2.10"
SPI-Provider:
javax.xml.parsers.DocumentBuilderFactory,org.apache.xerces.jaxp.SAXParserFactory
We could even go for a more generic approach that allows arbitrary
service properties to be specified:
SPI-Provider:
javax.xml.parsers.DocumentBuilderFactory;properties="provider-name:Xerces
2.10;my-other-prop:foobar"

I think we could also consider having a simple header:
SPI-Provider: true
which would inspect the META-INF/services directory and register
services for all providers it finds there...

Thoughts anyone?

David

Reply via email to