[hibernate-dev] Redefining the API/SPI/implementation split

Steve Ebersole steve at hibernate.org
Sat Dec 6 11:02:38 EST 2014


>
> Sometimes it's just convenience; we have an "util.JNDIHelper" which is
> needed in several modules (Massindexer statistics, JMS lookups, etc..)
> and I don't think we should expose it as an API nor that another
> project like Infinispan Query should ever use it.
>

It's funny you bring up JNDIHelper specifically.  ORM used to have a
JNDIHelper class as well and I went through this same exercise.  In ORM
JNDIHelper is now the JndiService (I treat "well known acronyms" as words
for the purpose of camel casing).  But the important point is that it is a
service, available from the service registry.  To me, access to the service
registries and their services overall, is an SPI concern.  If some 3rd
party integration wants to use Hibernate's JndiService as part of its
integration (and some cache integrations do), I am more than ok with that.



> > Isn't it our definition of a SPI?
>
> No. I just realised our definition of SPI isn't adequate as there are
> two different kinds of integration points.
>

In my opinion we have many more "levels" of SPI then just 2.  We have even
discussed how to handle some of the differences a few times in f2f or irc.

An SPI describes a contract meant for integration.  But there are many
parts to that.  You mentioned caching, so the main contract there is the
RegionFactory.  So obviously an integrator is implementing that.  The
RegionFactory is returning Region instances.  those 2 contracts need to
remain stable.  Since the integrations implement those contracts, any
changes of any kind to the contracts require changes to the implementation
(aside from certain cases involving supplied base implementations).  Most
of the methods on RegionFactory to build a Region accept
a CacheDataDescription argument.  CacheDataDescription is a "parameter
object".  Changes to CacheDataDescription do not generally require changes
to the implementation.  I like to think of it in terms of a component and
the data passed between Hibernate and that component.  So even though
RegionFactorty, Region and CacheDataDescription are all "spi contracts",
they fulfill very different roles in the concept of an SPI.  Some need to
be more stable than others.

I also think a lot in terms of "audience" when it comes to contracts.  I
might write a class intending it for use by a number of different roles:

   1. Another Hibernate class
   1. In the same module
      2. In another module
      3. In another Hibernate project, although I prefer to think of this
      more in line with an "Integration"
      2. Integration
      1. As the contract for an integration
      2. As the communication related to that integration
   3. Application - SessionFactory, Session, etc

Just wanted to clarify...

Personally, I like the phrase "friend" or "family" when describing the type
of thing you are discussing.  Not sure either of those work great as a
package name though to denote the idea of "stay away".


More information about the hibernate-dev mailing list