apache/seatunnel · error · UnsupportedOperationException
can't support custom load jar
Error message
can't support custom load jar
What it means
AbstractPluginDiscovery's DEFAULT_URL_TO_CLASSLOADER adds plugin jar URLs to a classloader via reflection, but only when the classloader is a URLClassLoader. On modern JDKs (9+) the application classloader is not a URLClassLoader, so any attempt to add custom plugin jar URLs throws UnsupportedOperationException('can't support custom load jar'). This fires in the discovery constructor when dynamic plugin jar loading is requested.
Source
Thrown at seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/AbstractPluginDiscovery.java:85
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
@SuppressWarnings("unchecked")
public abstract class AbstractPluginDiscovery<T> implements PluginDiscovery<T> {
private static final String PLUGIN_MAPPING_FILE = "plugin-mapping.properties";
/**
* Add jar url to classloader. The different engine should have different logic to add url into
* their own classloader
*/
private static final BiConsumer<ClassLoader, List<URL>> DEFAULT_URL_TO_CLASSLOADER =
(classLoader, urls) -> {
if (classLoader instanceof URLClassLoader) {
urls.forEach(url -> ReflectionUtils.invoke(classLoader, "addURL", url));
} else {
throw new UnsupportedOperationException("can't support custom load jar");
}
};
private final Path pluginDir;
private final Config pluginMappingConfig;
private final BiConsumer<ClassLoader, List<URL>> addURLToClassLoaderConsumer;
protected final ConcurrentHashMap<PluginIdentifier, Optional<List<URL>>> pluginJarPath =
new ConcurrentHashMap<>(Common.COLLECTION_SIZE);
protected final Map<PluginIdentifier, String> sourcePluginInstance;
protected final Map<PluginIdentifier, String> sinkPluginInstance;
protected final Map<PluginIdentifier, String> transformPluginInstance;
public AbstractPluginDiscovery(BiConsumer<ClassLoader, List<URL>> addURLToClassloader) {
this(Common.connectorDir(), loadConnectorPluginConfig(), addURLToClassloader);
}
public AbstractPluginDiscovery() {
this(Common.connectorDir(), loadConnectorPluginConfig());View on GitHub (pinned to cf67b549a7)
Solutions
- Place the plugin jar into the SeaTunnel plugin directory (connectors/ or lib/) so it is loaded at startup instead of dynamically
- Run on a JDK/mode where the classloader is a URLClassLoader, or launch with a custom URLClassLoader setup
- Remove the plugin jar path configuration so discovery uses classpath-based loading
Example fix
// before (config referencing external jar) plugin_jar_paths = ["/opt/my/custom-connector.jar"] // after # remove the jar path config; install the jar instead: cp /opt/my/custom-connector.jar $SEATUNNEL_HOME/connectors/
Defensive patterns
Strategy: fallback
Validate before calling
ClassLoader cl = Thread.currentThread().getContextClassLoader();
boolean dynamicJarLoadingSupported = cl instanceof URLClassLoader;
if (!dynamicJarLoadingSupported) {
// do not configure plugin jar URLs; place jars in the plugin dir instead
} Type guard
boolean supportsDynamicJarAdd(ClassLoader cl) {
return cl instanceof URLClassLoader;
} Try / catch
try {
discovery = new MyPluginDiscovery(pluginDir, pluginJars);
} catch (UnsupportedOperationException e) {
if ("can't support custom load jar".equals(e.getMessage())) {
log.warn("Dynamic jar loading unsupported on this JDK; install jars into the plugin dir instead");
} else {
throw e;
}
} Prevention
- Install plugins into $SEATUNNEL_HOME/connectors or lib instead of runtime jar injection
- On JDK 9+ never rely on adding URLs to the app classloader
- Document that custom jar paths require a URLClassLoader-based launch
When it happens
Trigger: Constructing an AbstractPluginDiscovery subclass with plugin jar URLs while running on a JDK whose application classloader is not a URLClassLoader (Java 9+), i.e. dynamic 'custom load jar' is requested but unsupported by the runtime.
Common situations: Running SeaTunnel on JDK 9+ where custom plugin jar loading was attempted; configuring plugin jar paths on a runtime that does not support adding URLs; launching the engine in a mode that expects dynamic jar injection.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- CONFIG_VALIDATION_FAILED
- Plugin %s not found.
- get plugin dependency jar path failed, pluginIdentifier: {}
- plugin dir: {} not exists, load plugin from classpath
- A decoding format must override this method to apply metadat
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0a53e084ff4b0f54.
Report an issue: GitHub.