{"record":{"id":"9ba9812dbede8cf6","repo":"apache/seatunnel","slug":"can-t-load-jar-use-current-thread-classloader-use","errorCode":null,"errorMessage":"can't load jar use current thread classloader, use URLClassLoader instead now. message: ","messagePattern":"can't load jar use current thread classloader, use URLClassLoader instead now\\. message: ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java","lineNumber":235,"sourceCode":"    @Override\n    public Optional<T> createOptionalPluginInstance(\n            PluginIdentifier pluginIdentifier, Collection<URL> pluginJars) {\n        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();\n        T pluginInstance = loadPluginInstance(pluginIdentifier, classLoader);\n        if (pluginInstance != null) {\n            log.info(\"Load plugin: {} from classpath\", pluginIdentifier);\n            return Optional.of(pluginInstance);\n        }\n        Optional<List<URL>> pluginJarPaths = getPluginJarPath(pluginIdentifier);\n        // if the plugin jar not exist in classpath, will load from plugin dir.\n        if (pluginJarPaths.isPresent()) {\n            try {\n                // use current thread classloader to avoid different classloader load same class\n                // error.\n                addURLToClassLoaderConsumer.accept(classLoader, pluginJarPaths.get());\n                addURLToClassLoaderConsumer.accept(classLoader, (List<URL>) pluginJars);\n            } catch (Exception e) {\n                log.warn(\n                        \"can't load jar use current thread classloader, use URLClassLoader instead now.\"\n                                + \" message: \"\n                                + e.getMessage());\n                URL[] urls = new URL[pluginJars.size() + 1];\n                int i = 0;\n                for (URL pluginJar : pluginJars) {\n                    urls[i++] = pluginJar;\n                }\n                urls =\n                        Stream.concat(Arrays.stream(urls), pluginJarPaths.get().stream())\n                                .distinct()\n                                .toArray(URL[]::new);\n                classLoader =\n                        new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());\n            }\n            pluginInstance = loadPluginInstance(pluginIdentifier, classLoader);\n            if (pluginInstance != null) {\n                log.info(","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java#L217-L253","documentation":"When adding plugin jar URLs to the current thread's classloader fails (the classloader doesn't support addURL, e.g., it's not a URLClassLoader), the discovery falls back to creating a new URLClassLoader over the plugin jars. This warning records the original exception message before falling back.","triggerScenarios":"createOptionalPluginInstance tried to append plugin jar paths to the thread context classloader, but the classloader type does not support URL appending (or a security/IO exception occurred), so it constructs a URLClassLoader instead.","commonSituations":"Running under application servers or module systems (e.g., OSGi-ish or JPMS) where the context classloader is not a URLClassLoader; engine wrappers that replace the default classloader.","solutions":["This is a self-healing fallback — verify the plugin actually loads afterward; if it does, the warning can be ignored","If plugin classes then fail to load, check for class isolation issues (classes loaded by different classloaders) and ensure the plugin's dependencies ship with it","Run with a standard setup (bin/seatunnel.sh) where the context classloader supports URL addition","Check the logged 'message:' text to identify the underlying addURL exception"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"ClassLoader cl = Thread.currentThread().getContextClassLoader();\nboolean canAddUrl = cl instanceof URLClassLoader;","typeGuard":"if (!(Thread.currentThread().getContextClassLoader() instanceof URLClassLoader)) { /* expect fallback path */ }","tryCatchPattern":null,"preventionTips":["Run with the standard seatunnel.sh launcher","Package plugin dependencies inside the plugin jar","Watch for classloader isolation errors after fallback"],"tags":["classloader","plugin-discovery","fallback"],"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-23T08:17:48.524Z"}