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...

robingrindrod
  • 474
  • 4
  • 18
Caroline
  • 381
  • 1
  • 4
  • 13

3 Answers3

37

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).

Philipp
  • 335
  • 1
  • 6
  • 17
axtavt
  • 239,438
  • 41
  • 511
  • 482
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 {

}
Xiao
  • 1,552
  • 2
  • 22
  • 20
  • 2
    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 http://mvnrepository.com/artifact/com.google.auto.service/auto-service – David Kinghorn Jan 07 '16 at 21:59
  • My pleasure! If you have improvements, please edit the answer for viewers from the future (in the future) – Xiao Jan 07 '16 at 22:10
  • This AutoService is brilliant! – Frankie Mar 29 '17 at 22:32
  • 1
    And nobody is afraid that is a release candidate? – paul Apr 08 '18 at 16:48
  • 3
    @paul 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. – Dagan Sandler Apr 18 '18 at 05:28
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)

Antoniossss
  • 31,590
  • 6
  • 57
  • 99