eclipse-vertx/vert.x · error · IllegalStateException
Cannot find META-INF/services/${clazz} on classpath
Error message
Cannot find META-INF/services/${clazz} on classpath What it means
Deprecated ServiceHelper.loadFactory(Class) uses the old ServiceLoader file lookup; if no implementation of clazz is registered under META-INF/services/<class name>, IllegalStateException('Cannot find META-INF/services/<clazz> on classpath') is thrown. It signals a required SPI implementation is missing from the runtime classpath.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/impl/ServiceHelper.java:27
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package io.vertx.core.impl;
import java.util.*;
/**
* A helper class for loading factories from the classpath.
*
* @author <a href="http://tfox.org">Tim Fox</a>
*/
public class ServiceHelper {
@Deprecated
public static <T> T loadFactory(Class<T> clazz) {
T factory = loadFactoryOrNull(clazz);
if (factory == null) {
throw new IllegalStateException("Cannot find META-INF/services/" + clazz.getName() + " on classpath");
}
return factory;
}
@Deprecated
public static <T> T loadFactoryOrNull(Class<T> clazz) {
Collection<T> collection = loadFactories(clazz);
if (!collection.isEmpty()) {
return collection.iterator().next();
} else {
return null;
}
}
@Deprecated
public static <T> List<T> loadFactories(Class<T> clazz) {
return loadFactories(clazz, null);
}View on GitHub (pinned to fb308bd8c3)
Solutions
- Add the dependency that provides the SPI implementation (e.g. io.vertx:vertx-hazelcast for clustering)
- Ensure your build/shading tool merges META-INF/services files (ServicesResourceTransformer for shade, mergeServiceFiles for Gradle)
- If on JPMS, add a provides ... with ... clause in module-info
- Migrate to the non-deprecated overload taking a ServiceLoader or ServiceHelper.loadFactoryOrNull with a fallback
Example fix
// before
ClusterManager cm = ServiceHelper.loadFactory(ClusterManagerFactory.class).newManager();
// after
ClusterManager cm = Optional.ofNullable(ServiceHelper.loadFactoryOrNull(ClusterManagerFactory.class))
.map(ClusterManagerFactory::newManager)
.orElseGet(HazelcastClusterManager::new); Defensive patterns
Strategy: fallback
Validate before calling
ClusterManagerFactory f = ServiceHelper.loadFactoryOrNull(ClusterManagerFactory.class);
if (f == null) throw new IllegalStateException("Add the clustering provider jar to the classpath"); Try / catch
try { factory = ServiceHelper.loadFactory(Spi.class); } catch (IllegalStateException e) { log.error("Missing SPI provider: add the implementation jar (check META-INF/services)"); throw e; } Prevention
- Include provider jars (e.g. vertx-hazelcast) in runtime deployment artifacts
- Configure shade plugin ServicesResourceTransformer / mergeServiceFiles
- Smoke-test the built jar in a clean environment
- Prefer explicit dependency injection of the factory over ServiceHelper when possible
When it happens
Trigger: Calling loadFactory(SomeSpi.class) (or Vert.x internals resolving e.g. ClusterManagerFactory, LogDelegateFactory, DNS resolver providers) when no provider file exists on the classpath.
Common situations: Building an uber-jar that strips META-INF/services entries; forgetting to add the provider implementation dependency (e.g. vertx-clustering-implementations) at runtime; packaging as JPMS module without 'provides' clauses.
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 service on the classpath or module path
- 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/4253a72441baebcc.
Report an issue: GitHub.