[hibernate-dev] Concept of "service availability"

Steve Ebersole steve at hibernate.org
Mon Aug 20 23:19:46 EDT 2012


This ties together a few different discussions that have been going on 
simultaneously on the mailing list that I think are all related.

Right now to configure certain services (select one impl over another) 
users generally give the FQN for that impl Class.  For example to use 
C3P0 connection pooling users would say:

hibernate.connection.provider_class = 
org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider

We have discussed why this is bad even before any of the OSGi 
discussions and the solution we wanted to shoot for was that of naming 
"selectors" such that the user would instead say:

hibernate.connection.provider_class = c3p0

And "c3p0" here would be interpreted to mean "instantiate and configure 
the 
org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider 
Class".  But that still means a limited set of short name values *and* 
still gives us a problem (iiuc) under OSGi due to visibility.

So what I propose instead is a way for service implementors to be 
registered under a short name via discovery.  The main piece to this is 
the "registry" (which is also a service under the BootstrapServiceRegistry):

interface AvailableServiceRegistry extends Service {
     public <T> Class<? extends T> 
findAvailableServiceImplementor(Class<T> serviceRole, String selector);
}

class AvailableServiceRegistryImpl
         implements AvailableServiceRegistry,
         ServiceRegistryAwareService {
     private Map<Class,Map<String,Class>> availableImplementors = ...;

     @Override
     public <T> Class<? extends T> 
findAvailableServiceImplementor(Class<T> serviceRole, String selector) {
         // purposely simplistic :)
         return availableImplementors.get( serviceRole ).get( selector );
     }

     @Override
     public void injectServices(ServiceRegistryImplementor 
serviceRegistry) {
         final LinkedHashSet<ServiceAvailabililtyNotifier> notifiers = 
serviceRegistry.getService( ClassLoaderService.class ).loadJavaServices( 
ServiceAvailabililtyNotifier.class );
         for ( ServiceAvailabililtyNotifier notifier : notifiers ) {
             for ( ServiceAvailabililty availability : 
notifier.getAvailabilities() ) {
                 // again, purposely simplistic
                 Map<String,Class> serviceImplementors = 
availableImplementors.get( availability.getRole() );
                 serviceImplementors.put(
                         availability.getSelector(),
                         availability.getImplementor()
                 );
             }
         }
     }
}



Outstanding question... Especially in OSGi, where service bundles can be 
added/removed, how do we best account for cleaning up no-longer valid 
references (even more importantly perhaps, what the hell does it mean to 
Hibernate when a ConnectionProvider implementation, for example, that is 
in use gets taken away?!?).  Perhaps this is just where an OSGi-specific 
Hibernate ServiceRegistry implementation would come into play.

-- 
steve at hibernate.org
http://hibernate.org


More information about the hibernate-dev mailing list