apache/incubator-seata · error · StoreException

class loader set error, you should not use the Bootstrap cla

Error message

class loader set error, you should not use the Bootstrap classloader

What it means

AbstractDataSourceProvider.validate() loads the configured JDBC driver class through getDriverClassLoader(); a null ClassLoader means the class was resolved via the Bootstrap classloader, which cannot see application jars like MySQL/PostgreSQL drivers. Seata refuses with StoreException rather than silently failing later, because store mode db requires an application-level loader to load driver classes.

Source

Thrown at core/src/main/java/org/apache/seata/core/store/db/AbstractDataSourceProvider.java:93

        this.dataSource = generate();
    }

    @Override
    public DataSource provide() {
        return this.dataSource;
    }

    public DataSource generate() {
        validate();
        return doGenerate();
    }

    public void validate() {
        // valid driver class name
        String driverClassName = getDriverClassName();
        ClassLoader loader = getDriverClassLoader();
        if (null == loader) {
            throw new StoreException("class loader set error, you should not use the Bootstrap classloader");
        }
        try {
            loader.loadClass(driverClassName);
        } catch (ClassNotFoundException exx) {
            String folderPath = System.getProperty("loader.path");
            if (folderPath == null) {
                folderPath = System.getProperty("java.class.path");
            }
            String driverClassPath = Stream.of(folderPath.split(File.pathSeparator))
                    .map(File::new)
                    .filter(File::exists)
                    .map(file -> file.isFile() ? file.getParentFile() : file)
                    .filter(Objects::nonNull)
                    .filter(File::isDirectory)
                    // Only the MySQL driver needs to be placed in the jdbc folder.
                    .map(file -> (MYSQL8_DRIVER_CLASS_NAME.equals(driverClassName)
                                    || MYSQL_DRIVER_CLASS_NAME.equals(driverClassName))
                            ? new File(file, "jdbc")

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Ensure the JDBC driver jar lives on the normal application classpath (lib/ directory of the seata-server distribution or your app's dependencies), not the boot/ext classpath.
  2. If you subclass/extend the provider, implement getDriverClassLoader() to return the class's own loader: `AbstractDataSourceProvider.class.getClassLoader()` or the thread-context classloader.
  3. Start with `java -jar`/standard scripts rather than -Xbootclasspath/-Djava.ext.dirs tricks.
  4. For seata-server, place the driver in the jdbc/ folder as documented so the shipped launcher loads it in the app loader.

Example fix

// before (custom provider)
@Override
protected ClassLoader getDriverClassLoader() {
    return null; // bootstrap loader -> StoreException
}

// after
@Override
protected ClassLoader getDriverClassLoader() {
    return Thread.currentThread().getContextClassLoader();
}
Defensive patterns

Strategy: validation

Validate before calling

ClassLoader cl = provider.getDriverClassLoader();
if (cl == null) {
    throw new IllegalStateException(
        "Driver classloader is null (bootstrap) - put the JDBC driver on the application classpath");
}
provider.generate();

Try / catch

try {
    dataSource = provider.generate();
} catch (StoreException e) {
    if (e.getMessage() != null && e.getMessage().contains("Bootstrap classloader")) {
        // classpath layout problem: fix launcher/driver location, then restart
        throw new IllegalStateException("Fix driver classpath location", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: getDriverClassLoader() returns null — typically when the driver class resolves through the bootstrap/platform classloader (e.g. driver on the JVM's boot classpath, or a custom ClassLoaderStrategy returning null), then validate() throws before any DataSource is generated.

Common situations: Seata Server started with the jar on java.ext.dirs or -Xbootclasspath; running inside certain containers/app-server classloader setups; a custom subclass of AbstractDataSourceProvider overriding getDriverClassLoader to return null; JDK 9+ module-path placement putting the driver out of the app loader.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/7d9292438452ba5a. Report an issue: GitHub.