alibaba/druid · error · SQLException

create exceptionSorter error

Error message

create exceptionSorter error

What it means

setExceptionSorter loads a class via Utils.loadClass and instantiates it via clazz.newInstance(), casting to ExceptionSorter. If the class loads but instantiation fails (abstract, inaccessible, constructor throws) or the cast fails, the cause is wrapped as SQLException("create exceptionSorter", ex). A null loadClass result is a separate LOG.error path that does NOT throw.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java:1380

        if (exceptionSorter == null) {
            this.exceptionSorter = NullExceptionSorter.getInstance();
            return;
        }

        exceptionSorter = exceptionSorter.trim();
        if (exceptionSorter.length() == 0) {
            this.exceptionSorter = NullExceptionSorter.getInstance();
            return;
        }

        Class<?> clazz = Utils.loadClass(exceptionSorter);
        if (clazz == null) {
            LOG.error("load exceptionSorter error : " + exceptionSorter);
        } else {
            try {
                this.exceptionSorter = (ExceptionSorter) clazz.newInstance();
            } catch (Exception ex) {
                throw new SQLException("create exceptionSorter error", ex);
            }
        }
    }

    @Override
    public List<Filter> getProxyFilters() {
        return filters;
    }

    public void setProxyFilters(List<Filter> filters) {
        if (filters != null) {
            this.filters.addAll(filters);
        }
    }

    public String[] getFilterClasses() {
        List<Filter> filterConfigList = getProxyFilters();

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Ensure the class implements com.alibaba.druid.pool.ExceptionSorter (or extend NullExceptionSorter/valid existing impls).
  2. Give it a public no-arg constructor and make the class public/concrete.
  3. Read SQLException.getCause() to distinguish ClassCastException from InstantiationException.
  4. Consider letting Druid auto-detect the exceptionSorter from the JDBC URL instead of setting it manually.

Example fix

// before
// ds.setExceptionSorter("com.example.WrongClass");

// after
// ds.setExceptionSorter("com.alibaba.druid.pool.vendor.MySQLExceptionSorter");
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Utils.loadClass(exceptionSorterFqn);
if (c == null) throw new IllegalStateException("exceptionSorter class not found: " + exceptionSorterFqn);
if (!com.alibaba.druid.pool.ExceptionSorter.class.isAssignableFrom(c))
    throw new IllegalStateException(exceptionSorterFqn + " is not an ExceptionSorter");
com.alibaba.druid.pool.ExceptionSorter probe = (com.alibaba.druid.pool.ExceptionSorter) c.newInstance();

Type guard

static boolean isValidExceptionSorter(String fqn) {
    try {
        Class<?> c = Class.forName(fqn);
        return com.alibaba.druid.pool.ExceptionSorter.class.isAssignableFrom(c)
            && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());
    } catch (Throwable t) { return false; }
}

Try / catch

try {
    ds.setExceptionSorter(fqn);
} catch (SQLException e) {
    if (e.getMessage().equals("create exceptionSorter error")) {
        Throwable cause = e.getCause(); // CCE / IE / constructor-thrown
        // ensure class implements ExceptionSorter, has public no-arg ctor, ctor succeeds
    }
    throw e;
}

Prevention

When it happens

Trigger: setExceptionSorter("com.example.MySorter") where MySorter loads but is not an ExceptionSorter, is abstract/inaccessible, or its constructor throws.

Common situations: Pointing exceptionSorter at a wrong class (e.g. a dialect class instead of an ExceptionSorter); a custom sorter with a non-public/no no-arg constructor; constructor depends on missing config.

Related errors


AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14). Data as JSON: /api/errors/4fa302f0936cad6f. Report an issue: GitHub.