Instead of building monolithic applications developers prefer modular and extendible applications. Either they want to use the flexible architecture by themselfs or provide a plug-in api for other developers. In both situations one must define a modul’s purpose and it’s boundary. This module boundary is also called the service provides interface (SPI) or also a plug-in api. Java’s jar file specification describes how service providers can provide their services so that others can lookup them. This pattern is known as the service locator pattern. Since Java 1.6 the ServiceLoader has been added in order to make service provider lookup easy for application developers. Prior to Java 1.6 applications developers had to implement the lookup on their own based on the jar file specification. But you can also use third-party libraries like commons-discovery.

In this blog I want to demonstrate how you can use standard java to locate service providers.

The service provider interface (SPI)

First we must define an interface for a service that can be plugged in. In this example I will just use a simple greeting service, because the focus of this blog is on using a spi.

Service provider implementations

Service providers must implement the service provider interface and should be bundled in seperate jar files. Even if multiple service providers can be bundled in one jar it is better to divide them in seperate jars so that you can simply add or remove them from the classpath in order to activate or deactivate a service provider.

A casual greeting service provider

The next step is to implement the service provider interface to provide a specific service. The next source code example shows a simple casual greeting service.

After the service provider has been implemented you publish that service as described by the jar file specification.

To do that you must define a text file that contains the full-quallified provider class name. This text file is named the service provider configuration and must be named after the full-quallified interface name and placed in META-INF/services.

casual-greeting-service-provider

Another formal greeting service provider

In this blog I also want to demonstrate how service providers can be activated and deactivated using the classpath. Therefore I add another service provider here.

Of course this service provider also needs to be published using a service provider configuration file.

formal-greeting-service-provider

Lookup and use service providers

Since Java 1.6. you can use the ServiceLoader api to lookup service providers for an service interface. In this simple example I will use a small main class that does the job.

Build the example code

You can download the compiled example code here as zip file. (Java 1.7 needed)

or build it. You can get the full source code at github.

Run the example with different classpath

In the example code zip file you will find these jars

  • java-spi.jar
    This jar only contains the service provider interface.
  • java-spi-client.jar
    This jar file contains the main class that looks up service providers
  • java-spi-casual-greeting-service.jar
    This jar only contains the casual greeting service implementation.
  • java-spi-formal-greeting-service.jar
    This jar only contains the formal greeting service implementation.

In the example zip file you will also find two bat files that you can use on windows.

If you run the example with only the casual greeting service the classpath will look like this.

or replace the casual greeting service with the formal greeting service

At least you can also run the example with both services