[hibernate-dev] Standalone service registry

Karl von Randow karl+hibernate at xk72.com
Thu Jan 16 14:48:43 EST 2014


On 17/01/2014, at 1:42 am, Steve Ebersole <steve at hibernate.org> wrote:

> On 01/16/2014 02:42 AM, Karl von Randow wrote:
>> Hi all,
>> 
>> I had a conversation with Steve today on IRC about refactoring the org.hibernate.service package to make it standalone. The service registry implementation is mostly separable from Hibernate core already, and it could be useful in other applications perhaps where hibernate-core isn’t a dependency. I found myself in that exact situation, which is why I’m here.
>> 
>> I have done a test extraction of the service registry classes, excluding the BootServiceRegistry, ClassLoaderService and StrategySelector families. This was quite straight forward, worked well and worked with Hibernate core.
>> 
>> Steve suggested that the boot service registry and associated class loading functionality would be useful standalone as well. To see what that is like, I have now done a test extraction including the BootServiceRegistry, ClassLoaderService and StrategySelector families. It has worked quite well, but was definitely major.
> What do you mean it "was ... major"?  Difficult?  I would think that those would all peel-away pretty easily; that it would be "quite straight forward" as you said.


The first part, without Boot + Class + StrategySelector is easy. The only interesting dependencies are HibernateException, CoreMessageLogging and JmxService. I resolved all of those pretty easily, and migrated JmxService into the org.hibernate.service.spi package, next to its marker class Manageable.

I moved two log methods from CoreMessageLogging to the new ServiceRegistryMessageLogging. The generated source is working nicely in Gradle, I presume there will be an i18n implication for this.

The majorness (or is it major-ity) of the second part is related to the question below - there were quite a few places where there was ORM specific functionality woven in. So from that point of view, the standaloning may also be considered beautiful from a code structure pov.

…


> 
>> The most interesting parts of migrating BootServiceRegistry et al over to the SSR is the Hibernate ORM dependencies in BootServiceRegistry - specifically Integrators. There were also Hibernate ORM specific features in StrategySelectorBuilder and ClassLoaderServiceImpl (specifically ClassLoaderHelper). I have created subclasses in hibernate-core of the implementations I moved to the SSR module, with the same class name as the original. These subclasses provide the Hibernate specific functionality.
> 
> Ah, I had forgotten about the direct Integrator reference on BootServiceRegistry.  I'd have to think through that.
> 
> What "ORM specific features" are in StrategySelectorBuilder and ClassLoaderServiceImpl?

I managed to separate Integrator pretty nicely I think. Hibernate core has its own BootServiceRegistry implementation that supports Integrators by subclassing the new AbstractBootServiceRegistry in SSR. I added the necessary hooks - one or two.

StrategySelectorBuilder loads dialects, JTA platforms, transaction factories and multi-table bulk id strategies as part of its code. Again, this was easily separated out. I created an AbstractStrategySelectorBuilder in SSR and a subclass StrategySelectorBuilder, in its original place in core, that overrides a new addBaseline(StrategySelectorImpl) protected method and calls the addDialects etc methods extracted from the original. Pretty clean.

The StrategyRegistrationProvider was a bit interesting. This is referenced by its full class name as property files in the individual modules to load strategy registration providers. As you’ll note from the commit log I only discovered this later in the migration. So I’ve added the capability to AbstractStrategySelectorBuilder to specify the StrategyRegistrationProvider sub-interface to use, modifying the original StrategyRegistrationProvider in core to extend the new one in SSR. This works pretty well. I’ve then created a DefaultStrategySelectorBuilder to live in SSR which uses the StrategyRegistrationProvider base-interface and doesn’t have any baseline strategies.

ClassLoaderServiceImpl has a dependency on ClassLoaderHelper, which allows overriding of the context class loader. From the comments, this is a temporary solution, but I obviously wanted to maintain it. There was also a deprecated method fromConfigSettings(Map configValues) which is called from PersistenceXmlParser in JPA that I didn’t want to bring to SSR as it contains core specific reference (AvailableSettings.HIBERNATE_CLASSLOADER etc). I modified the original ClassLoaderServiceImpl to be a subclass of the impl in SSR and to contain those specific pieces of functionality. I also modified the BootstrapServiceRegistryBuilder so that it could choose the default ClassLoaderService implementation, and core’s builder chooses core’s one.

I did all of the changes in little steps in the commit logs, so when it comes to the point of following the process it should be pretty easy to see the thinking in each step!

> 
>> Another interesting standalone issue is the exception hierarchy. The exceptions no longer extend from HibernateException. Perhaps it would be possible to have that class in the SSR package and core to address this.
> Not ideal, but not a deal-breaker either.  Not convinced that *all* exceptions should be runtime-variety anyway.


I only had to modify two tests, IIRC, that relied on those exceptions being HibernateException subclasses. It doesn’t seem likely that much user code relies on those exceptions as they feel much more internal to ORM. *fingers-crossed-emoji*



More information about the hibernate-dev mailing list