[hibernate-dev] [OGM and others] API, SPI and FPI

Steve Ebersole steve at hibernate.org
Fri May 23 11:10:10 EDT 2014


The split packages were really a vehicle to make auto-generation of osgi
metatdata possible.  It is nice too that they offer a quick visual clue
into the intent.  I agree that an annotation would work as well for some
aspects of this.  But using annotations would make the osgi auto-gen harder
for sure (doable still, just harder).

I agree we are all describing the same thing: integration points between 2
things (sometimes 2 projects, sometimes 2 modules, sometimes just 2 classes
or "services").  Personally I like to call them "touch points" as in the
point were things touch.  I am much less interested in what we call them
versus doing them right :)  We all agreed 2-3 years ago to call them SPI.
 I see no reason to change that simply because there is not a "nice, neat
wikipedia page" to talks about our view of these concepts.



On Thu, May 22, 2014 at 11:03 AM, Sanne Grinovero <sanne at hibernate.org>wrote:

> Looks like we're all aligned?
> Steve made some concrete examples, Emmanuel pointed out how we have
> been defining this vs. apparently other people.
>
> I don't feel the need to change our interpretation, if that's what is
> being discussed.
>
> It's good to remember that there are different kinds of SPIs; we
> indeed came to the conclusion that it's often much nicer to have an
> abstract class when the SPI is meant to be provided by 3rd party code
> but I think we need an interface in that case as well (in addition to
> the abstract class).
>
> Also breaking an SPI could bring as much pain as an API change.. when
> an API changs the user is often in the position to be able to do
> something about it. More often people get in trouble because they are
> using a mixture of versions of different frameworks and libraries
> which are meant to work together, and they don't.. in such scenarios
> the user might not be able to do something about it, other than
> lobbying and begging for fixes and releases in projects out of his
> control.
> An API change just invalidates project for people who are not able to
> recompile, and makes books and training outdated :) Sure that's
> annoying too, my point is just that SPI is not less important
> *generally* but it depends on what API and what SPI we're talking
> about.
>
> But even when we discuss the same "kind" of SPIs, some are more
> critical than others, and some are "internal" SPIs (like
> hibernate-search to hibernate-search module), some are very close
> (hibernate-orm to hibernate-search) some are slightly further down
> (infinispan - hibernate-search).. others need critical stability
> (container integration, etc..). And of course it's less painfull when
> it affects something that 99% of users didn't know it existed in the
> first place.
>
> Conclusion, the package name will never set a rule: to me it's more
> like a reminder to be carefull in any way possible as "someone" is
> going to hate me. I am personally not even a fan of these specific
> package naming conventions, an annotation would be just as good,
> provided it gets somehow visibility in the javadoc (or even hides
> javadocs for internals).
>
>
> Sanne
>
> On 22 May 2014 15:32, Steve Ebersole <steve at hibernate.org> wrote:
> > Deja vu as we have had this exact discussion before (and actually, our
> > discussions pre-date those TAG discussions....)
> >
> > You are basing your specific reading of what SPI means based on a single
> > wikipedia page that goes out of its way to point out its incompleteness
> :)
> >  And really even then in my opinion you are reading too much into its
> > mention of the JDK ServiceLoader.  What the wikiepdia says specifically
> is:
> >
> > *Service Provider Interface* (SPI) is an
> > API<http://en.wikipedia.org/wiki/Application_programming_interface>
> > intended
> >> to be implemented or extended by a third party. It can be used to enable
> >> framework extension and replaceable components
> >
> >
> > That's actually not much different (if at all) from how I use the term
> SPI.
> >  To me, SPI is simply "the API that is used between internal components
> to
> > accomplish something".  A specific important distinction here is that
> APIs
> > are meant for application code to bind to, SPIs are not.  As I have
> pointed
> > out probably 100 times already, yes there are 2 facets to this.  To me an
> > SPI is made up of:
> > 1) The SPI contracts that are meant to be extended by users and/or 3rd
> > parties.
> > 2) The SPI contracts that are not intended for extension.
> >
> > Another correlated break down is:
> > 1) SPI contracts that do things
> > 2) SPI contracts that are inputs/outputs to (1)
> >
> > Take for example, the idea of scanning deployments for annotated classes
> > (mainly because this one is fresh in my mind).  The main SPI contract
> here
> > is Scanner and ArchiveDescriptorFactory.  These are each intended as
> > extension points, they both "do stuff".  All the rest of the "scanning
> spi"
> > is inouts/outputs to these 2.  Why is this an important distinction?
>  Well,
> > generally speaking where we get into trouble in terms of "changing SPIs"
> > later is when we change this first group.  When we have to make
> > changes to Scanner
> > or make changes to ArchiveDescriptorFactory we cause problems downstream
> > for folks that implement/extend this stuff.  That's where patterns like
> > parameter objects and delegates are sooooooooo beneficial.  As an
> > illustration, say we need to pass some new information into the single
> > Scanner method (this was the recent case I worked through).  If that
> means
> > adding a new parameter to that Scanner method, well that just screwed
> every
> > implementor of the Scanner interface because now their implementation is
> no
> > longer valid.  If instead, Scanner had made use of parameter objects (it
> > now does btw), the parameter object itself would have been changed
> causing
> > no problem of existing Scanner implementations.  The "parameter object"
> is
> > still part of the SPI.  But it falls into this second category.  Changing
> > these guys is essentially irrelevant in terms of causing no issues for
> > existing SPI implementations.
> >
> >
> > And as far as "a tendency to consider the application developer more
> sacred
> > than the framework/integrator when it comes to breaking backward
> > compatibility" I would not phrase it like that.  There are  a few parts
> to
> > this in my mind:
> >
> > First,  I think you need to step back and look at the bigger picture.
>  The
> > API defines the features that Hibernate is exposing to the application
> > (save this thing, find that thing).  Its kind of broad and generally
> avoids
> > defining a feature in relation to an interaction between 2 things.  SPIs
> in
> > many ways are inherently more complicated to design because they need to
> > consider both sides of the problem.  Going back to scanning, that SPI
> needs
> > to consider Hibernate's requirements from scanning as well as any
> > requirements the implementation needs especially accounting for any
> quirks
> > in the various potential implementations.
> >
> > Second, because of the "overlap" or "integration" aspects between teams
> and
> > projects there needs to be coordination and cooperation when
> > building/designing an SPI.  To be honest, this part has been lacking even
> > within "our team" across projects because people get focused on their
> work.
> >  What happens instead, again from my perspective, is no
> > coordination/cooperation
> > occurs in the building/designing of these; and then later people get
> upset
> > when the SPI needs to change because it was not well designed to begin
> > with.  Another aspects of this is "more eyes"; the more people involved
> in
> > the design of an API (SPI fits in here equally) looking at it, the better
> > designed it will be.
> >
> >
> > All that said, I don't plan on changing use of the phrase SPI based on (a
> > questionable interpretation of) one wikipedia page.
> >
> >
> > On Thu, May 22, 2014 at 4:21 AM, Emmanuel Bernard <
> emmanuel at hibernate.org>wrote:
> >
> >> (This discussion is around OGM but it is a very generic subject
> applicable
> >> to all projects.)
> >>
> >> I made a mistake in naming the spi packages SPI because the definition
> of
> >> SPI is quite narrow and even more narrower in Java than elsewhere.
> >>
> >> ## Definitions
> >>
> >> ### SPI
> >>
> >> In Java and according to Wikipedia, a SPI (Service provider interface)
> is
> >> related to the notion of ServiceLoader
> >> http://en.wikipedia.org/wiki/Service_Provider_Interface
> >> We certainly do not (or very rarely) have these kinds of services in our
> >> SPI packages.
> >>
> >> Another point of you comes from this StackOverflow article
> >>
> https://stackoverflow.com/questions/2954372/difference-between-spi-and-api
> >>
> >> - the API is the description of classes/interfaces/methods/... that you
> >> call and use to achieve a goal and
> >> - the SPI is the description of classes/interfaces/methods/... that you
> >> extend and implement to achieve a goal
> >>
> >> A third point of you is the NetBeans one
> >> http://wiki.netbeans.org/DevFaqApiSpi
> >>
> >> SPI stands for Service Provider Interface. It is a subset of all things
> >> that can be API specific to situations where a library is providing
> classes
> >> which are called by the application (or API library), and which
> typically
> >> change the things the application is able to do.
> >>
> >> I think everyone agrees that an SPI is kind of API.
> >>
> >> ### IPI or FPI (Integrator / Framework Public Interface)
> >>
> >> I will use FPI as it tastes better than IPI but I have no preferences
> over
> >> integrators vs frameworks.
> >>
> >> Now in my mind and for some obscure reasons, SPI really meant FPI. To my
> >> credit, I have done that fairly constantly on Hibernate Search and Bean
> >> Validation. Hibernate OGM was never properly packaged initially so
> that’s
> >> another story.
> >>
> >> A FPI is used by a framework integrating or extending the project
> exposing
> >> these FPIs.
> >>
> >> ## What does really matter?
> >>
> >> It is useful to differentiate an API used from an API extended (SPI)
> >> because the constraints are different:
> >>
> >> - APIs used can add new methods and should be interfaces rather than
> >> classes.
> >> - APIs extended (SPIs) should be abstract classes so that a new contract
> >> added can be offered by the project without breaking implementors.
> >>
> >> But from a user point of you, I’m tempted to say "so what?”. It does not
> >> change your inclination to make use of that contract.
> >>
> >> It is useful to differentiate application developer(*) facing APIs from
> >> framework/integrator facing APIs (FPIs) to keep the API simple to use
> and
> >> to document. There is also a tendency to consider the application
> developer
> >> more sacred than the framework/integrator when it comes to breaking
> >> backward compatibility.
> >>
> >> (*) I say application developer here but it really the primary user
> group
> >> of your project whereas the integrators are usually less numerous and
> more
> >> controllable.
> >>
> >> To me the latter (API/FPI) is more generally useful and that is the one
> I
> >> wish to separate in different packages naming conventions.
> >> The former it seems to me is very often self-obvious to the user and
> >> project maintainers. And from a usage PoV, it does not really matter.
> Plus
> >> there are cases where a contract is both used and extended (JDBC’s
> >> Connection contract for example).
> >>
> >> Can and should we split according to both dimensions? I don’t think so.
> >> And if I have to chose, I’d prefer to split according to the API/ FPI
> >> dimension which is more generally useful to our customers and makes it
> >> clear what is non breakable (API), what is inconvenient to break (FPI),
> >> what is free lunch (implementation).
> >>
> >> ## References
> >>
> >> There has been some discussions in the past as well
> >> https://issues.jboss.org/browse/TAG-47
> >>
> >> Emmanuel
> >> _______________________________________________
> >> hibernate-dev mailing list
> >> hibernate-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> >>
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>


More information about the hibernate-dev mailing list