geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guillaume Nodet <>
Subject Re: Adding OSGi support to Geronimo spec jars.
Date Fri, 26 Feb 2010 14:22:48 GMT
If you're working on a fresh implementation, I have some thoughts I
gathered in the past months when writing / using the ServiceMix Specs.
A few shortcomings of the current implementation are:
  * a given bundle does not have a way to select a particular
implementation, i think we should define a header that may allow
customizing the provider used for this very bundle
  * there is currently no isolation between the client and the
provider.  I think we should proxy the provider so that if it the
bundle goes away, the implementation could be replaced underneath
  * specify in which order the provider is selected.  One possible
solution would be to default to the provider with the lowest bundle id
(which is something used in several places in OSGi).  This must be
specified and easy to deal with (i.e. the user must be able to easily
control which one will be used).

Just my 2 cents.

On Fri, Feb 26, 2010 at 14:35, Rick McGuire <> wrote:
> I've been taking a hard look at what Servicemix had done to the various spec
> jars to make them better behaved in an OSGi environment.  This is being done
> with the intent of adding similar support to the base Geronimo spec jars.
>  I'm taking a fresh approach to this rather than necessarily just copying
> what Servicemix is doing.  I've found a number of interesting things during
> this process, so I thought it would be good to do a brain dump of what I've
> found and how I'm planning on implementing this.
> The basics of the Servicemix approach is to add an Activator to each of the
> spec bundle that maintains a registry of factory class information.  Each
> spec bundle have a listener that tracks bundle activity and will check for
> factory information in the META-INF/services directory of each started
> bundle.  Each started bundle has its own listener and own copy of the
> factory information.  The registry information is used in the various places
> spec code needs to dynamically load provider classes for different
> subsystems.  For example, loading a persistence provider.  All classloading
> is done lazily when a request is made for a matching class file.  The spec
> code retrieves the loaded classes and handles all details of creating the
> instances using the retrieved classes.
> Jarek Gawor suggested I might want to take a look at what the Aries project
> had for processing the META-INF/services information.  This test
> implementation, called "spifly", uses the OSGi extender pattern to inspect
> the META-INF/services directories and uses that information to automatically
> register services in the OSGi services registry.  In this situation, the
> classes are eagerly loaded, instances are created (which requires a
> no-argument constructor) and the services are registered in the OSGi
> registry.
> So, we have one set of information, but two different interpretations of how
> this information should be used.  The new implementation I was working on
> was using the extender pattern to maintain a single registry of this
> information that could be accessed using a provider registry service.  This
> would have a single listener, with a single version of the registry, and
> each bundle that required the service would just have a thin accessor layer
> to call the registry service if it was available.  This is essentially
> combining the approaches used by Servicemix and spifly.
> However, I was becoming increasingly concerned about this dual
> interpretation of the META-INF/services information, and started researching
> what conventions were in play with this.  What I found was there is a new
> feature in Java SE 6 called the ServiceLoader:
> The service loader uses the META-INF/services information to create mappings
> between interface classes and concrete implementations of these interfaces.
>  This is similar to the spifly approach, but there are a few fundamental
> differences.  The biggest difference is that each instance of the
> ServiceLoader class will instantiate a new instance of the implementation
> class when needed.  For spifly, there is only ever a single instance of the
> service created.  Both spifly and Servicemix are only processing the first
> line of the services files, while the ServiceLoader defines that an
> individual definition file can define a one-to-many interface/implementation
> mapping.  So, now we're up to 3 different interpretations of the
> META-INF/services information.
> Looking a little deeper into how Servicemix was using this information, I
> found that it was bending the intent of the META-INF/services information a
> bit.  The ServiceLoader definitions are intended to create mappings between
> interface classes and implementers of a given interface.  The service mix
> lookups were being used to directly resolve implementation classes.  To do
> this, the service definition file would need to use the same class as both
> interface name and implementer class.  This has a nice side effect of
> allowing particular implementations to be selectively replaced, but this is
> a usage that could cause problems if the information was picked up by either
> spifly or ServiceLoader.  This violated the fundamental assumption that this
> information defined interface-to-implementation mappings.
> In addition, the javamail changes were using this information to define
> protocol-to-provider mappings.  For example, an "smtp" javamail provider
> implementation class.  In this case, the mapping did not even start with the
> name of a Java class.  This definitely conflicted with both spifly and
> ServiceLoader.
> A lot of these difficulties go away if I decouple the Servicemix semantics
> by moving the information to a different location so that we're not seeing
> multiple interpretations of what the data in META-INF/services means.  The
> code I'm working on will be looking in OSGI-INF/providers, and the mapping
> information is defined in terms of a provider identifier-to-provider class
> mapping.  This is really is the interpretation used by the Servicemix code,
> but removes the conflicting usage.
> Rick

Guillaume Nodet
Open Source SOA

View raw message