jd-opensource/joyagent-jdgenie · error · JdbcBizException

未找到支持 的JdbcDialectFactory实现类

Error message

未找到支持%s的JdbcDialectFactory实现类

What it means

load() found JdbcDialectFactory implementations on the classpath, but none of them returns true from acceptsURL(url) for the given JDBC URL, so no dialect can handle it. The URL is interpolated into the message.

Solutions

  1. Fix the JDBC URL so it matches a supported scheme (e.g. jdbc:mysql://host:3306/db, jdbc:postgresql://...)
  2. Add the dialect factory jar for the target database to the classpath
  3. Log/inspect the exact URL passed in; verify acceptsURL() logic of your custom factory covers the URL format
  4. If using a custom JdbcDialectFactory, add the URL pattern to its acceptsUrl match

Example fix

// before
String url = config.getUrl(); // "mysql://host:3306/db"
JdbcDialect dialect = JdbcDialectLoader.load(url);
// after
String url = config.getUrl();
if (!url.startsWith("jdbc:")) {
    url = "jdbc:" + url;
}
JdbcDialect dialect = JdbcDialectLoader.load(url); // "jdbc:mysql://host:3306/db"
Defensive patterns

Strategy: validation

Validate before calling

boolean urlSupported(String url) {
    if (url == null || !url.startsWith("jdbc:")) return false;
    String scheme = url.substring(5, url.indexOf(':', 5) == -1 ? url.length() : url.indexOf(':', 5));
    return ServiceLoader.load(JdbcDialectFactory.class).stream()
        .anyMatch(f -> f.acceptsURL(url));
}

Try / catch

try {
    JdbcDialect dialect = JdbcDialectLoader.load(url);
} catch (JdbcBizException e) {
    throw new IllegalArgumentException(
        "Unsupported JDBC URL scheme: " + url + "; supported: " + supportedSchemes(), e);
}

Prevention

When it happens

Trigger: Calling JdbcDialectLoader.load(url) with a malformed or unsupported JDBC URL (wrong prefix/scheme, e.g. missing 'jdbc:' prefix, unknown database type like jdbc:unknowdb://...) while dialect factories exist but reject the URL.

Common situations: Typo in JDBC URL prefix; using a database brand whose dialect factory is not on the classpath even though other dialects are; URL built dynamically from config with a bad jdbcType placeholder; extra whitespace/case issues in the scheme.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/ba2a9782c29e9271. Report an issue: GitHub.

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/data/jdbc/dialect/JdbcDialectLoader.java:30

public final class JdbcDialectLoader {

    private JdbcDialectLoader() {
    }


    public static JdbcDialect load(String url) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        List<JdbcDialectFactory> foundFactories = discoverFactories(cl);

        if (foundFactories.isEmpty()) {
            throw new JdbcBizException("JdbcDialectFactory无实现类");
        }

        final List<JdbcDialectFactory> matchingFactories =
                foundFactories.stream().filter(f -> f.acceptsURL(url)).toList();

        if (matchingFactories.isEmpty()) {
            throw new JdbcBizException(String.format("未找到支持%s的JdbcDialectFactory实现类", url));
        }

        return matchingFactories.get(0).create();
    }

    private static List<JdbcDialectFactory> discoverFactories(ClassLoader classLoader) {
        try {
            final List<JdbcDialectFactory> result = new LinkedList<>();
            ServiceLoader.load(JdbcDialectFactory.class, classLoader)
                    .iterator()
                    .forEachRemaining(result::add);
            return result;
        } catch (ServiceConfigurationError e) {
            throw new JdbcBizException("JdbcDialectFactory无实现类" + e.getMessage(), e);
        }
    }
}

View on GitHub (pinned to 2417e0b8b6)