ServiceLoader to find implementations of an interface
Asked Answered
T

3

25

I tried to use the Java ServiceLoader to find all classes that implement a specific interface like so:

loader = ServiceLoader.load(Operation.class);
try {
    for (Operation o : loader) {
        operations.add(o);
    }
} catch (ServiceConfigurationError e) {
    LOGGER.log(Level.SEVERE, "Uncaught exception", e);
}

Unfortunately, when I run Eclipse in debug mode the ServiceLoader doesn't find any classes. I feel like I'm missing a trivial point...

Twitch answered 24/4, 2012 at 18:44 Comment(1)
Do you have META-INF/services/fqcn.Operation configured?Tripe
Q
38

ServiceLoader cannot do it.

In order to expose class as a service that can be discovered by ServiceLoader you need to put its name into provider configuration file, as described in Creating Extensible Applications With the Java Platform .

There are no built-in ways find all classes that implement a particular interface. Frameworks that can do something similar use their own classpath scanning solutions (and even with custom classpath scanning it's not easy because .class files only store information about interfaces implemented directly, not transitively).

Qua answered 24/4, 2012 at 18:54 Comment(0)
A
26

If the implementations are ones that you wrote yourself, you could use AutoService to make them available through the ServiceLoader interface, eg

@AutoService(Operation.class)
class Foo implements FooInterface {

}

@AutoService(Operation.class)
class Bar extends Foo {

}
Act answered 12/7, 2015 at 2:5 Comment(5)
Thanks so much for this suggestion! I just couldn't get the provider file to work. Must have been putting it in the wrong place or with a typo or something, but this worked right out of the box with maven. You can find the latest version in the maven repository at mvnrepository.com/artifact/com.google.auto.service/auto-serviceStink
My pleasure! If you have improvements, please edit the answer for viewers from the future (in the future)Act
This AutoService is brilliant!Simard
And nobody is afraid that is a release candidate?Stephanus
@Stephanus I don't think it's a problem in this case. ServiceLoader is pretty straight forward to utilize directly (just need to stick to the naming scheme under META-INF). AutoService gives you an easy shortcut using an annotation - but it still does just that - create a single file with the correct naming scheme under META-INF.Apotheosis
H
3

In order to scan your classpath at runtime for implementations of specific interface you would need to use different solution eg. Reflections (notice s on the end, this is not java's Reflection API)

Hanan answered 17/8, 2016 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.