[hibernate-dev] Concept of "service availability"

mailing at bibbernet.org mailing at bibbernet.org
Tue Aug 28 16:10:41 EDT 2012


On 08/28/2012 09:40 PM, Steve Ebersole wrote:
> Imagine we have acme.jar.  acme.jar provides a new TransactionFactory 
> to Hibernate for a new way to integrate with transactions.  For 
> hopefully obvious reasons Hibernate jars/bundles cannot name acme.jar 
> as a import nor as a dependency (whatever the correct OSGi parlance is 
> there).  So under normal circumstances, Hibernate would have no 
> knowledge of the ClassLoader that would allow access to acme.jar 
> resources.  Therefore, "out of the box" discovery will not work here.

Ok in osgi, acme.jar would provide a service which implements the 
interface TransactionFactory (and thus also Service).
Hibernate would use a ServiceListener or ServiceTracker or some other 
way to get informed when a new service is available which implements the 
TransactionFactory (or Service) interface or in the init phase scanns 
for already registered services which implement this interfaces.

In both situations, hibernate afterwards has the ServiceReferences 
(which could be used to get the bundle) and can get classes/resources 
from this service + it gets an Instance of the TransactionFactory which 
is defined through the service.

>
> Further lets say that a user wants to make use of this Hibernate+acme 
> integration.  So in order to build a 
> SessionFactory/EntityManagerFactory we would need to know about this 
> acme.jar supplied service.

Like before .. listen for ServiceRegistrations of Services which 
implement the interface TransactionFactory
>
> So my last reply on this thread was about what needs to happen given 
> this situtation.
>
> The first approach would be that acme.jar gets registered with 
> Hibernate as a service (however that happens).  Meaning a call would 
> be made to 
> org.hibernate.boot.registry.selector.spi.StrategySelector#registerStrategyImplementor 
> based on the work I have done for this under HHH-7552. 

I would acme.jar only register a osgi service with the appropriate 
interfaces, thats all for acme.jar.
Hibernate would use a constuct, lets call it OsgiServiceHelper, to do 
the OSGI ServiceListening and ServiceTracking and once it finds 
interesting services (like the one from acme.jar) it would do the 
registerStrategyImplementor and even unregister once a OSGI service is 
no longer available.


> The problem here is that this is not the service exposed by the 
> Hibernate bundle; a SessionFactory/EntityManagerFactory is.  But in 
> order to build a SessionFactory/EntityManagerFactory we need the 
> acme.jar TransactionFactory service.  This is the chicken-egg.

This is what I meant with "iterative" approach .. a 
SessionFactory/EntityManagerFactory is dependent on other services which 
could be not yet available and thus must be ignored or put on hold until 
all needed services are available.

>
> The other approach I saw was that Hibernate could be aware of the 
> acme.jar bundle through the ClassLoader(s) that get registered with 
> its ClassLoaderService.  Then auto-discovery would work.

This could be done in the same way .. acme.jar would expose a osgi 
service which implements a certain marker interface (like a 
ClassLoaderService with only one method getClassLoader()) - and 
hibernate could track/listen to services which implement this marker 
interface.


>
>
> On Tue 28 Aug 2012 02:13:15 PM CDT, mailing at bibbernet.org wrote:
>> On 08/28/2012 02:39 PM, Steve Ebersole wrote:
>>> The problem there is timing.  Hibernate already has to be started in
>>> order
>>> for "this" to work.  But what "this" is doing is providing things
>>> Hibernate
>>> needs to start.  Its chicken-egg.
>>>
>>> Interestingly this is very similar to the proposal Scott Marlow and I
>>> made
>>> to the JPA group.  And in fact that could be leveraged here.
>>> Essentially
>>> that proposal was to make JPA bootstrapping a 2-phase process rather
>>> than
>>> just a single "build it" phase.  Here however that would mean (iiuc, 
>>> and
>>> please correct me if I do not) Hibernate needing 2 OSGi services.
>>> One that
>>> builds the BootstrapServiceRegistry and MetadataSources/Configuration
>>> and
>>> then another that builds the SessionFactory/EntityManagerFactory.
>>> The type
>>> of things you discuss here would depends on the first service but
>>> somehow
>>> need to be ordered before the second Hibernate service.
>>
>> I have seen (and developed) many services which use a kind of
>> iterative process. If they discover a service A which is interesting
>> for them and realize they need another service B which is not yet
>> available, they put the service A on hold (whatever on hold means),
>> until a bundle, which announce service B is available (or they wait
>> forever if no bundle ever announces a service B) and then continue
>> with the handling of service A.
>>
>> This could be implemented with the help of
>> ServiceTracker,ServiceListener and/or BundleListener (and other
>> standard osgi classes and interfaces)
>>
>> I normally implement it in the following way:
>>
>> The BundleActivator implements the ServiceListener and or
>> BundleListener and reacts on Service-Events(modified properties,
>> service registered, service unregistered) or Bundle-Events (bundle
>> installed, uninstalled, resolved, unresolved, starting, stopping,
>> etc.). This could be used to initiate a scan of the bundle for
>> resources, register/unregister interesting services, etc.
>>
>> So hibernate in the osgi framework could do a multi step bootstrap like:
>> - On Bundle start (when the BundleActivator gets called), register
>> Bundle- , ServiceListeners and ServiceTrackers to get hold on
>> modifications which occur from now on (and track the services and/or
>> bundles of interest if events got passed to the listeners).
>> - Next step would be to look if there are already interesting services
>> (and bundles) which got activated before the hibernate bundle got
>> activated (and add them to the list of tracked bundles and/or service
>> if they are not already tracked ).
>>
>> From now on, you could then react on life-cycle changes for bundles
>> and services and modify the internal registries accordingly ( or do
>> some other meaningful things with the information)
>>
>> this means you have two phases:
>> - Initialisation and discovery of bundles and service which are
>> already present.
>> - Dynamic life cycle which react on bundle and service changes.
>>
>>> Of course assuming we even want to go that route in Hibernate
>>> source.  The
>>> other option is the OSGi container adding that bundle to the
>>> ClassLoader it
>>> passes Hibernate so Hibernate can do the auto-discovery.  Maybe I am
>>> missing some options?
>>
>> Please correct me, but if you have a Bundle (or ServiceReference which
>> could be used to get the implementing Bundle) you can use the bundle
>> to load classes and resources which are contained in the bundle (yes I
>> know there are also Permissions in OSGI, but you can grant the
>> hibernate bundle(s) the appropriate permissions to be allowed to load
>> classes in that way - but the permission system is another issue which
>> shouldn't cause problems here)
>>
>>
>
> -- 
> steve at hibernate.org
> http://hibernate.org



More information about the hibernate-dev mailing list