Out-of-the-box, the Java API offers a specific form of Inversion of Control. It’s implemented by the Service Loader class. It is designed to locate implementation classes of an interface on the classpath. This way allows to discover which available implementations of an interface are available on the classpath at runtime, and thus paves the way for modules designed around a clean separation between an API module - i.e. JAR, and multiple implementation modules.

This is the path chosen by the logging framework, SLF4J. SLF4J itself is just the API, while different implementations are available (_e.g. Logback, Log4J, etc.). SLF4J clients only interact with the SLF4J API, while the implementation available on the classpath takes care of the nitty-gritty details at runtime.

It’s implemented as a file located in the META-INF/services folder of a JAR. The name of the file is the fully qualified name of the interface, while its content is a list of qualified names of available implementations. For example, for an interface ch.frankel.blog.serviceloader.Foo , there must be a file named META-INF/services/ch.frankel.blog.serviceloader.Foo which content might look like this:

ch.frankel.blog.serviceloader.FooImpl1 ch.frankel.blog.serviceloader.FooImpl2

Note classes listed above must implement the ch.frankel.blog.serviceloader.Foo interface.

From a code perspective, it’s very straightforward: