On May 24, 2010, at 2:18 PM, David Blevins wrote:

> Having a look at this code and trying to figure out what the impact is on 
> non-Geronimo consumers who might be using OSGi.
> 
> The geronimo-osgi-registry seems fairly small (just 10 classes including the 
> inner classes) and only using the OSGi core and compendium jars.
> 
> I grocked from the description that it is used to look for a provider of the 
> related API jar, but didn't get some specifics.
> 
>  1. Using EJB as an example, how does one say "I am a provider".  There is no 
> "i am the EJB container" interface to implement so what exactly are we 
> looking for?


EJB is not an example.  the provider stuff works for 2 situations:

1. Service providers, where you have a META-INF/services/<interface-name> file 
containing one line, the name of an implementing class in the current jar 
(bundle)  In this case, put a SPI-Provider manifest header in and your class 
will be accessible to service consumers via ProviderLocator.getServices(...) 
and related methods.

2. you need to make a class from your bundle available to others without them 
knowing about or getting inside your bundle.  Put a Export-SPI-provider header 
in your manifest whose value is a comma separated list of the classes you want 
to make available.  Consumers can load the classes by calling 
ProviderLocator.loadClass(className);
> 
>  2. What is the effect if the Activator is activated and no provider is found?

There are 2 activators.  I guess you mean the one in provider-locator?  If it 
isn't found, then you fall back on normal classloader tricks for trying to find 
services classes.  These won't normally work in an osgi environment.

thanks
david jencks

> 
> 
> Any insight?
> 
> 
> -David
> 
> 
> On Feb 26, 2010, at 5:35 AM, 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:
>> 
>> http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html
>> 
>> 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
>> 
> 

Reply via email to