eclipse-vertx/vert.x · error · IllegalStateException
Cannot find service on the classpath or module path
Error message
Cannot find service on the classpath or module path
What it means
ServiceHelper.loadFactory(ServiceLoader) checks a supplied ServiceLoader for any provider instance and throws IllegalStateException('Cannot find service on the classpath or module path') when none is found. Same missing-SPI condition as the class-based variant, but resolution is done by the caller's ServiceLoader (supports module path).
Source
Thrown at vertx-core/src/main/java/io/vertx/core/impl/ServiceHelper.java:66
public static <T> List<T> loadFactories(Class<T> clazz, ClassLoader classLoader) {
if (classLoader != null) {
return loadFactories(ServiceLoader.load(clazz, classLoader));
}
classLoader = Thread.currentThread().getContextClassLoader();
List<T> list = loadFactories(ServiceLoader.load(clazz, classLoader));
if (list.isEmpty() && classLoader != ServiceHelper.class.getClassLoader()) {
// By default, ServiceLoader.load uses the TCCL, this may not be enough in environment dealing with
// classloaders differently such as OSGi. So we should try to use the classloader having loaded this
// class. In OSGi it would be the bundle exposing vert.x and so have access to all its classes.
list = loadFactories(ServiceLoader.load(clazz, ServiceHelper.class.getClassLoader()));
}
return list;
}
public static <T> T loadFactory(ServiceLoader<T> factories) {
T factory = loadFactoryOrNull(factories);
if (factory == null) {
throw new IllegalStateException("Cannot find service on the classpath or module path");
}
return factory;
}
public static <T> T loadFactoryOrNull(ServiceLoader<T> factories) {
Collection<T> collection = loadFactories(factories);
if (!collection.isEmpty()) {
return collection.iterator().next();
} else {
return null;
}
}
public static <T> List<T> loadFactories(ServiceLoader<T> factories) {
List<T> list = new ArrayList<>();
if (factories.iterator().hasNext()) {
factories.iterator().forEachRemaining(list::add);
return list;View on GitHub (pinned to fb308bd8c3)
Solutions
- Add a META-INF/services/<fully.qualified.Spi> file naming the implementation, or a `provides Spi with Impl;` clause in module-info.java
- Verify the implementation jar is on the classpath/module path at runtime
- Check the services file name exactly matches the SPI interface FQN (no whitespace/typos)
- Use loadFactoryOrNull to handle absence gracefully
Example fix
// before
// module-info.java has no provides clause
requires io.vertx.core;
// after
requires io.vertx.core;
provides io.vertx.core.spi.cluster.ClusterManagerFactory
with io.vertx.spi.cluster.hazelcast.HazelcastClusterManagerFactory; Defensive patterns
Strategy: fallback
Validate before calling
boolean present = ServiceLoader.load(Spi.class).iterator().hasNext();
if (!present) throw new IllegalStateException("No provider for " + Spi.class.getName()); Try / catch
try { impl = ServiceHelper.loadFactory(loader); } catch (IllegalStateException e) { impl = defaultImpl(); } Prevention
- Add `provides Spi with Impl;` in module-info for JPMS apps
- Keep META-INF/services files with correct FQCN filenames
- Verify with `jar --describe-module` or listing services entries in CI
- Prefer passing your own instance over ServiceLoader in application code
When it happens
Trigger: Creating a ServiceLoader.load(SomeSpi.class) that yields zero providers and passing it to loadFactory(loader) — no 'provides' in module-info and no META-INF/services entry.
Common situations: JPMS modularized apps missing `provides SomeSpi with SomeImpl`; classpath apps whose jar lacks the services descriptor; typos in the fully-qualified provider class name in META-INF/services/<interface>.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- Cannot find META-INF/services/${clazz} on classpath
- No ClusterManagerFactory instances found on classpath
- Nesting more than two levels is not supported
- Cannot find vertx-version.txt on classpath
- ${packageFolderURL} is not a JAR file
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/a41b13dc00a4c2b9.
Report an issue: GitHub.