jd-opensource/joyagent-jdgenie · error · JdbcBizException

Multiple jdbc dialect factories can handle

Error message

Multiple jdbc dialect factories can handle

What it means

JdbcCatalogLoader.load throws JdbcBizException('Multiple jdbc dialect factories can handle') when more than one discovered JdbcCatalogFactory claims the same DialectEnum. The loader refuses to guess between ambiguous providers.

Solutions

  1. Run mvn dependency:tree (or gradle dependencies) and exclude duplicate dialect provider jars.
  2. Remove or de-register the redundant JdbcCatalogFactory service registration.
  3. If intentional, change the loader to select a preferred factory deterministically instead of throwing.

Example fix

// before (pom.xml)
<dependency>genie-data-jdbc-mysql:1.0</dependency>
<dependency>genie-data-jdbc-mysql-legacy:1.2</dependency> <!-- also registers mysql factory -->
// after (pom.xml)
<dependency>genie-data-jdbc-mysql:1.2</dependency>
<!-- legacy jar excluded -->
Defensive patterns

Strategy: try-catch

Validate before calling

// detect duplicate providers before load
long count = discoverFactories(cl).stream()
    .filter(f -> f.jdbcDialect() == dialect).count();
if (count > 1) {
    throw new IllegalStateException("Duplicate dialect provider for " + dialect);
}

Try / catch

try {
    JdbcCatalog catalog = JdbcCatalogLoader.load(dialect);
} catch (JdbcBizException e) {
    if (e.getMessage().contains("Multiple jdbc dialect factories")) {
        // run dependency:tree, exclude duplicate jar, rebuild
    } else throw e;
}

Prevention

When it happens

Trigger: load(dialect) where two or more factories on the classpath return jdbcDialect() equal to the requested dialect — typically caused by duplicate/conflicting provider jars (two versions of the same dialect module, or two modules claiming the same dialect).

Common situations: Dependency mediation pulled in two versions of the same dialect artifact; a custom factory registered alongside the stock one for the same dialect; fat-jar merging multiple META-INF/services entries from different jars.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/data/jdbc/catalog/JdbcCatalogLoader.java:35


    public static JdbcCatalog load(DialectEnum jdbcDialect) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        List<JdbcCatalogFactory> foundFactories = discoverFactories(cl);

        if (foundFactories.isEmpty()) {
            throw new JdbcBizException(String.format(
                    "Could not find any jdbc dialect factories that implement '%s' in the classpath.",
                    JdbcCatalog.class.getName()));
        }

        final List<JdbcCatalogFactory> matchingFactories =
                foundFactories.stream().filter(f -> f.jdbcDialect() == jdbcDialect).toList();
        if (matchingFactories.isEmpty()) {
            throw new CatalogException("Could not find any jdbc dialect factory that can handled ");
        }
        if (matchingFactories.size() > 1) {
            throw new JdbcBizException("Multiple jdbc dialect factories can handle");
        }

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


    private static List<JdbcCatalogFactory> discoverFactories(ClassLoader classLoader) {
        try {
            final List<JdbcCatalogFactory> result = new LinkedList<>();
            ServiceLoader.load(JdbcCatalogFactory.class, classLoader)
                    .iterator()
                    .forEachRemaining(result::add);
            return result;
        } catch (ServiceConfigurationError e) {
            log.error("Could not load service provider for Catalog factory.", e);
            throw new JdbcBizException(
                    "Could not load service provider for Catalog factory.", e);
        }

View on GitHub (pinned to 2417e0b8b6)