The Service Loader Mechanism

by: Ethan McCue

If you have an interface or abstract class defined in some jar

package whatever.project;

public interface DoesThing {
   void doThing();
}

And in another jar you have one or more implementations of that interface which has a zero argument constructor

package something.other;

public final class DoesThingImpl {
    @Override
    public void doThing() {
        System.out.println("I implemented this in a certain way");
    }
}

as well as a file in that jar with the interface name under META-INF/services

META-INF/services/whatever.project,DoesThing

which has a line that has the name of the implementing class

something.other.DoesThingImpl

Then you can obtain an implementation of that interface via the service loader mechanism

var loader = ServiceLoader.load(DoesThing.class);
for (var thingDoer : loader) {
    thingDoer.doThing();
}

This is some really core magic and is how most of the projects that want you to just add dependencies to get functionality - like slf4j, jdbc, twelvemonkeys, etc - use to do their thing


<- Index