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 <emman...@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@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