{"record":{"id":"b97c329c66cf0526","repo":"apache/seatunnel","slug":"unsupported-classloader-classloaderclassname","errorCode":null,"errorMessage":"Unsupported classloader: ${classLoaderClassName}","messagePattern":"Unsupported classloader: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-core/seatunnel-flink-starter/seatunnel-flink-starter-common/src/main/java/org/apache/seatunnel/core/starter/flink/execution/FlinkAbstractPluginExecuteProcessor.java","lineNumber":65,"sourceCode":"                    urls.forEach(url -> ReflectionUtils.invoke(classLoader, \"addURL\", url));\n                } else {\n                    try {\n                        // In Java 8, AppClassLoader is a subclass of URLClassLoader, so classLoader\n                        // instanceof URLClassLoader will return true. However, in Java 11, due to\n                        // the introduction of the modular system, AppClassLoader is no longer a\n                        // subclass of URLClassLoader, and this check will return false. To be\n                        // compatible with both Java 8 and Java 11, we can use reflection to\n                        // dynamically call the addURL method of URLClassLoader.\n                        Optional<Method> method =\n                                ReflectionUtils.getDeclaredMethod(\n                                        URLClassLoader.class, \"addURL\", URL.class);\n                        if (method.isPresent()) {\n                            for (URL url : urls) {\n                                method.get().invoke(classLoader, url);\n                            }\n                        }\n                    } catch (Exception e) {\n                        throw new RuntimeException(\n                                \"Unsupported classloader: \" + classLoader.getClass().getName(), e);\n                    }\n                }\n            };\n\n    protected FlinkRuntimeEnvironment flinkRuntimeEnvironment;\n    protected final List<? extends Config> pluginConfigs;\n    protected JobContext jobContext;\n    protected final List<T> plugins;\n    protected final Config envConfig;\n    protected final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n\n    protected FlinkAbstractPluginExecuteProcessor(\n            List<URL> jarPaths,\n            Config envConfig,\n            List<? extends Config> pluginConfigs,\n            JobContext jobContext) {\n        this.pluginConfigs = pluginConfigs;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-core/seatunnel-flink-starter/seatunnel-flink-starter-common/src/main/java/org/apache/seatunnel/core/starter/flink/execution/FlinkAbstractPluginExecuteProcessor.java#L47-L83","documentation":"RuntimeException thrown by FlinkAbstractPluginExecuteProcessor's classloader-wrapper when it tries to add plugin jar URLs to the current classloader via reflection (addURL method) but the classloader is not a URLClassLoader (or equivalent) supporting addURL. It wraps the reflective invocation exception and names the unsupported classloader class.","triggerScenarios":"Running the Flink starter on an environment where the context classloader is not a URLClassLoader (e.g. Flink's child-first or an application-server classloader without addURL), so method lookup or invoke fails inside the Callable.","commonSituations":"Embedding SeaTunnel in another application with a custom classloader; Flink version changes replacing URLClassLoader; running inside containers that swap the thread context classloader.","solutions":["Ensure the job runs with the standard Flink runtime classloader (URLClassLoader-based)","Avoid embedding the starter in environments that override the context classloader","If a custom classloader is required, make it extend URLClassLoader or expose an addURL-equivalent method"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"ClassLoader cl = Thread.currentThread().getContextClassLoader();\nif (!(cl instanceof URLClassLoader)) {\n    throw new IllegalStateException(\"Job requires a URLClassLoader-based context classloader, got: \" + cl.getClass().getName());\n}","typeGuard":"boolean isUrlClassLoader(ClassLoader cl) {\n    return cl instanceof URLClassLoader;\n}","tryCatchPattern":"try {\n    processor.execute();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported classloader\")) {\n        log.error(\"Context classloader lacks addURL: {}\", e.getCause(), e);\n    }\n    throw e;\n}","preventionTips":["Run on standard Flink runtime classloaders","Do not override the thread context classloader when embedding the starter","Keep custom classloaders extending URLClassLoader"],"tags":["flink","classloader","reflection"],"backgroundTag":"unsupported-platform","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}