OSGI has two classes/interfaces for dealing with Service Tracking - ServiceTracker and ServiceTrackerCustomizer, which could be used to create a OSGI-auto-discovery (and auto-cleanup)-Helper for hibernate:
A simple skeleton could look like: package org.bibbernet.osgi; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTrackerCustomizer; public class MyServiceTrackerCustomizer implements ServiceTrackerCustomizer { @Override public Object addingService(ServiceReference reference) { // a new service matching the criteria of the ServiceTracker can be added to the ServiceTracker // get the service object Object service = reference.getBundle().getBundleContext().getService(reference); // TODO: -> add service to hibernate service registry or if we we don't want if to get tracked, // return null // reference.getBundle() could be used to return service; } @Override public void modifiedService(ServiceReference reference, Object service) { // nothing todo - only service properties are modified } @Override public void removedService(ServiceReference reference, Object service) { // TODO: -> remove service from hibernate service registry // release this service reference reference.getBundle().getBundleContext().ungetService(reference); } } ------------------------------------- package org.bibbernet.osgi; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.Filter; import org.osgi.util.tracker.ServiceTracker; public class MyActivator implements BundleActivator { private ServiceTracker myServiceTracker; @Override public void start(BundleContext context) throws Exception { // Create a LDAP-like-Filter which matches the interested services // or better the interested interfaces the service should implement Filter filter = context.createFilter("(" + Constants.OBJECTCLASS + "=xxx.yyy.zzz)"); myServiceTracker = new ServiceTracker(context, filter, new MyServiceTrackerCustomizer()); // start tracking myServiceTracker.open(); } @Override public void stop(BundleContext context) throws Exception { // close ServiceTracker to ensure all service references get released if (myServiceTracker != null) { myServiceTracker.close(); } } } The bundle implementing the service then simple needs to announce a service with one of the watched interfaces - once the service gets started, hibernate gets announced and could use either the service object itself or the bundle defining the service - with this approach you could also use the bundle's classloader to load classes with bundle.loadClass() or access resources within the bundle with bundle.findEntries(), etc. - Martin On 08/27/2012 07:34 PM, Steve Ebersole wrote: > Not sure this will actually help with OSGi in terms of auto-discovery > at all after thinking about it some more. The problem is that in order > for auto-discovery to happen, Hibernate would need to have visibility > into the jar defining the service anyway in order to auto-discovery it. > > On the bright side, I realized another benefit. It would finally be > possible to report the available types of a particular > service/strategy. For example, show me all the available > ConnectionProviders; all the available Dialects; etc... > > > On Fri 24 Aug 2012 08:51:09 PM CDT, Steve Ebersole wrote: >> Would be nice to consolidate the notions of >> "ServiceAvailabililtyNotifier" and "ServiceContributor" (that I just >> added on metamodel). Such that a ServiceContributor would be able to >> regsiter the short names as well. >> >> >> On Thu 23 Aug 2012 03:58:10 PM CDT, Steve Ebersole wrote: >>> Ok, going to start working this up on master tomorrow. We will just >>> tackle the "going away" problem if/when it actually arises. >>> >>> On Tue 21 Aug 2012 05:55:31 PM CDT, Steve Ebersole wrote: >>>> Everyone else ok with this idea? >>>> >>>> On Tue 21 Aug 2012 08:27:25 AM CDT, Steve Ebersole wrote: >>>>> Not so concerned about shutdown situations. >>>>> >>>>> More, imagine a custom ConnectionProvider implementation provided by >>>>> user. And the use case of upgrading that implementation "in flight". >>>>> I think thats the OSGi use case. And not so sure Hibernate should be >>>>> implementing this self healing. I guess it depends how deeply we want >>>>> to support the OSGi model above and beyond JSE/JEE >>>>> >>>>> Obviously a used ConnectionProvider just going away is going to render >>>>> the SessionFactory using it broken. >>>>> >>>>> On Tue 21 Aug 2012 08:22:11 AM CDT, Scott Marlow wrote: >>>>>> On 08/20/2012 11:19 PM, Steve Ebersole wrote: >>>>>>> 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. >>>>>>> >>>>>> Adding Jesper as we were talking about how to handle "quiescence >>>>>> shutdown" at the AS level, which sounds related. Once we take the >>>>>> ConnectionProvider away, I would expect the Hibernate >>>>>> session(s)/session factory to be broken. If/when the >>>>>> ConnectionProvider comes back, Hibernate would need to re-establish >>>>>> it. I'm thinking that we need a neutral (autonomic) API/SPI for >>>>>> attempting to re-establish the ConnectionProvider. >>>>>> >>>>>> For the most part, a "quiescence shutdown" of the AS, would mean >>>>>> keeping the ConnetionProvider alive until the end (of the planned >>>>>> shutdown). I'm thinking that being able to re-establish the >>>>>> ConnectionProvider would still be useful (for AS "quiescence >>>>>> shutdown"), especially if something goes wrong during the shutdown >>>>>> and >>>>>> manual intervention is needed. >>>>>> >>>>>> To me, the process of re-establishing the ConnectionProvider, >>>>>> could be >>>>>> labeled "self healing" (with the help of an autonomic API/SPI). >>>>>> >>>>> -- >>>>> st...@hibernate.org >>>>> http://hibernate.org >>>> -- >>>> st...@hibernate.org >>>> http://hibernate.org >>> -- >>> st...@hibernate.org >>> http://hibernate.org >> -- >> st...@hibernate.org >> http://hibernate.org > -- > st...@hibernate.org > http://hibernate.org > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev