Why is this such a hassle?
For that we need to take a look in the JDK source ServiceLoader.java:
public S next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
String cn = nextName;
nextName = null;
try {
S p = service.cast(Class.forName(cn, true, loader)
.newInstance());
providers.put(cn, p);
return p;
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
} catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated: " + x,
x);
}
throw new Error(); // This cannot happen
}
If it encounters a ClassNotFoundException it doesn't emmit which class it can not find. Also the original exception is swallowed, so any diagnostic information within is lost.
They got one thing right though: fail. ;-)