{"record":{"id":"1deaae6355e58394","repo":"apache/seatunnel","slug":"could-not-find-any-factories-that-implement-s-i","errorCode":null,"errorMessage":"Could not find any factories that implement '%s' in the classpath.","messagePattern":"Could not find any factories that implement '(.+?)' in the classpath\\.","errorType":"validation","errorClass":"FactoryException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java","lineNumber":345,"sourceCode":"            return Optional.empty();\n        }\n        final List<T> matchingFactories =\n                foundFactories.stream()\n                        .filter(f -> f.factoryIdentifier().equalsIgnoreCase(factoryIdentifier))\n                        .collect(Collectors.toList());\n        if (matchingFactories.isEmpty()) {\n            return Optional.empty();\n        }\n        checkMultipleMatchingFactories(factoryIdentifier, factoryClass, matchingFactories);\n        return Optional.of(matchingFactories.get(0));\n    }\n\n    public static <T extends Factory> T discoverFactory(\n            ClassLoader classLoader, Class<T> factoryClass, String factoryIdentifier) {\n        final List<T> foundFactories = discoverFactories(classLoader, factoryClass);\n\n        if (foundFactories.isEmpty()) {\n            throw new FactoryException(\n                    String.format(\n                            \"Could not find any factories that implement '%s' in the classpath.\",\n                            factoryClass.getName()));\n        }\n\n        final List<T> matchingFactories =\n                foundFactories.stream()\n                        .filter(f -> f.factoryIdentifier().equalsIgnoreCase(factoryIdentifier))\n                        .collect(Collectors.toList());\n\n        if (matchingFactories.isEmpty()) {\n            throw new FactoryException(\n                    String.format(\n                            \"Could not find any factory for identifier '%s' that implements '%s' in the classpath.\\n\\n\"\n                                    + \"Available factory identifiers are:\\n\\n\"\n                                    + \"%s\",\n                            factoryIdentifier,\n                            factoryClass.getName(),","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java#L327-L363","documentation":"FactoryUtil.discoverFactory throws this FactoryException when the ServiceLoader found no factories at all implementing the requested factory class (e.g. TableSourceFactory) on the classpath. This fires before identifier matching, so it means the entire factory SPI failed to load, not just the requested plugin.","triggerScenarios":"Calling discoverFactory(classLoader, TableSourceFactory.class, id) when discoverFactories() returns an empty list — no META-INF/services/org.apache.seatunnel.api.table.factory.Factory resources visible to the classloader.","commonSituations":"Connector jars not installed in the plugins/connectors directory; fat jar missing SPI service files after shading; custom classloader that excludes SeaTunnel service files; running from an IDE without connector modules on the classpath.","solutions":["Install the SeaTunnel connectors: sh bin/install-plugin.sh <version>.","Verify META-INF/services/org.apache.seatunnel.api.table.factory.Factory exists inside the connector jar.","Check the classloader passed to discoverFactory actually includes the connector jars.","If building a shaded jar, ensure SPI files are not filtered out by the shade plugin."],"exampleFix":"// before (custom classloader with only app jars)\nURLClassLoader cl = new URLClassLoader(new URL[]{appJar});\n// after\nURLClassLoader cl = new URLClassLoader(new URL[]{appJar, connectorJar}, FactoryUtil.class.getClassLoader());","handlingStrategy":"validation","validationCode":"List<Factory> all = FactoryUtil.discoverFactories(classLoader);\nif (all.isEmpty()) {\n    throw new IllegalStateException(\"No SeaTunnel factories on classpath; install connectors first\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    TableSourceFactory f = FactoryUtil.discoverFactory(cl, TableSourceFactory.class, id);\n} catch (FactoryException e) {\n    throw new IllegalStateException(\"Connector jars missing from classpath — run install-plugin.sh\", e);\n}","preventionTips":["Run sh bin/install-plugin.sh after installing SeaTunnel.","When building custom fat jars, keep META-INF/services files unfiltered.","Verify the SPI file name is exactly org.apache.seatunnel.api.table.factory.Factory."],"tags":["spi","classpath","service-loader","factory"],"backgroundTag":"resource-not-found","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}