{"record":{"id":"aa0e6cf15b8949e6","repo":"apache/seatunnel","slug":"could-not-load-service-provider-for-factories","errorCode":null,"errorMessage":"Could not load service provider for factories.","messagePattern":"Could not load service provider for factories\\.","errorType":"exception","errorClass":"FactoryException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java","lineNumber":409,"sourceCode":"    }\n\n    @SuppressWarnings(\"unchecked\")\n    public static <T extends Factory> List<T> discoverFactories(\n            ClassLoader classLoader, Class<T> factoryClass) {\n        return discoverFactories(classLoader).stream()\n                .filter(f -> factoryClass.isAssignableFrom(f.getClass()))\n                .map(f -> (T) f)\n                .collect(Collectors.toList());\n    }\n\n    public static List<Factory> discoverFactories(ClassLoader classLoader) {\n        try {\n            final List<Factory> result = new LinkedList<>();\n            ServiceLoader.load(Factory.class, classLoader).iterator().forEachRemaining(result::add);\n            return result;\n        } catch (ServiceConfigurationError e) {\n            LOG.error(\"Could not load service provider for factories.\", e);\n            throw new FactoryException(\"Could not load service provider for factories.\", e);\n        }\n    }\n\n    /**\n     * This method is called by SeaTunnel Web to get the full option rule of a source.\n     *\n     * @return Option rule\n     */\n    public static OptionRule sourceFullOptionRule(@NonNull TableSourceFactory factory) {\n        OptionRule sourceOptionRule = factory.optionRule();\n        if (sourceOptionRule == null) {\n            throw new FactoryException(\"sourceOptionRule can not be null\");\n        }\n\n        Class<? extends SeaTunnelSource> sourceClass = factory.getSourceClass();\n        if (factory instanceof SupportParallelism\n                // TODO: Implement SupportParallelism in the TableSourceFactory instead of the\n                // SeaTunnelSource","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java#L391-L427","documentation":"FactoryUtil.discoverFactories throws this FactoryException when the JDK ServiceLoader fails with a ServiceConfigurationError while iterating Factory providers — i.e. a class named in an SPI service file cannot be loaded or instantiated (missing class, NoClassDefFoundError, constructor failure).","triggerScenarios":"ServiceLoader.load(Factory.class, classLoader) iteration throws ServiceConfigurationError because a provider class listed in META-INF/services is missing, has an incompatible dependency version, or fails in its static initializer.","commonSituations":"Connector jar with a missing transitive dependency; shaded jar missing/relocating classes the SPI references; JVM module/classloader visibility issues; corrupted jar in the plugins directory.","solutions":["Read the LOG.error stack trace to identify which provider class failed and why.","Fix the missing/conflicting dependency for that connector jar (often shading or version conflict).","Remove or repair the corrupted connector jar from the plugins directory.","Verify the provider class has a public no-arg constructor and implements Factory."],"exampleFix":"// before: jar missing shade-relocated guava -> ServiceConfigurationError\n// after: rebuild connector with dependency relocation or add the missing jar to the classpath","handlingStrategy":"try-catch","validationCode":"try (var urls = ServiceLoader.load(Factory.class, classLoader)) {\n    urls.iterator().forEachRemaining(f -> {}); // dry-run to surface ServiceConfigurationError early\n}","typeGuard":null,"tryCatchPattern":"try {\n    factories = FactoryUtil.discoverFactories(classLoader);\n} catch (FactoryException e) {\n    if (e.getCause() instanceof ServiceConfigurationError) {\n        LOG.error(\"Broken SPI provider jar: {}\", e.getCause().getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Inspect server logs at startup — the ServiceConfigurationError names the failing class.","Run shaded builds and confirm SPI-referenced classes are present (checkForServiceLoaderIssues).","Validate connector jars (unzip -t) after copying them into the plugins directory."],"tags":["spi","service-loader","classpath","dependency"],"backgroundTag":"class-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}