Avaje SPI

Discord Source API Docs Issues Releases
Discord Github Javadoc Github



The Java Service Provider Interface uses configuration files to find and load concrete implementations of given service provider interfaces. The downside of this system is that configuration files are not checked by the java compiler. As such it is a common occurence to forget to add the correct entries.

This zero-dependency library uses annotation processing to automatically generate the required META-INF/services entries for annotated classes. In addition, it will validate that the required provides clauses are present in an application's module-info files.

Dependency

To use this library add the avaje-spi-service as a provided/optional dependency. (The dependencies need only be included at compile-time and are not required at runtime)

<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>avaje-spi-service</artifactId>
  <version>1.2</version>
  <optional>true</optional>
  <scope>provided</scope>
</dependency>

@ServiceProvider

On classes that you'd like registered, place the @ServiceProvider annotation. As long as you only have one interface/ superclass, that type is assumed to be the SPI interface. So given the example below:

@ServiceProvider
public class BassServiceProvider implements MusicService {
  ...
}

Multi-Interfaced classes

If you have multiple interfaces and/or a base type, the library cannot infer the contract type. In such a case, we specify the contract type explicitly in the @ServiceProvider:

@ServiceProvider(MusicService.class)
public class BassServiceProvider extends Instrument implements Stringed, MusicService {
  ...
}

Module Validation

For modular projects, the processor will validate that all the required provides clauses are accounted for. A compile error describing what `provides` statements are missing will be throw if validations fail. So given the following class and module-info:

@ServiceProvider
public class BassServiceProvider implements MusicService {
  ...
}
module my.module {

  requires static io.avaje.spi;
  //provides not defined
}

You will get the compile error:

  Compilation failure /src/main/java/module-info.java:[1,1]
  Missing `provides MusicService with BassServiceProvider;`