What are the Service Provider Interfaces (SPI) ?

These are important elements of the Java platform. More documentation is available in the official tutorial. In a few words, you probably have noticed the Java APIs mainly consist in interfaces. The SPI is the mechanism setting up the appropriate implementation so that programs don't rely on the implementation at compile time.

When an implementation is provided, to associate it to the implemented interface, there is one (or more) entry point. For example, the JPA API has for single point the interface javax.persistence.spi.PersistenceProvider . All other interfaces are available via this one.

If you want to provide a JPA implementation, you first have to code a class implementing this interface. Then, a text file named after the fully qualified name of the interface should be available to the class loader setting up the environment in the META-INF/services directory.
This mean, if you are working with Eclipse IDE in a Java SE environment with an src source directory :

This text file just has to contain the available implementations. If I want my own implementation (the provider is org.test.jpaimpl.PersistenceProvider) to be available along with EclipseLink (the provider is org.eclipse.persistence.jpa.PersistenceProvider ) the file has to contain these two lines : 


For the specific case of JPA, when multiple implementations are found by the class loader, the implementation to use can be specified in the persistence.xml file, in the provider element of a persistence-unit :

<persistence version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="COLLECTIONS" transaction-type="RESOURCE_LOCAL">