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
- 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.
- If you subclass/extend the provider, implement getDriverClassLoader() to return the class's own loader: `AbstractDataSourceProvider.class.getClassLoader()` or the thread-context classloader.
- Start with `java -jar`/standard scripts rather than -Xbootclasspath/-Djava.ext.dirs tricks.
- 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
- Run Seata with its standard launcher (bin/seata-server.sh) which wires the correct classloaders.
- Put JDBC drivers in the distribution's jdbc//lib folders, never on -Xbootclasspath.
- In embedded/custom providers, always return a real ClassLoader from getDriverClassLoader().
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
- the {%s} can't be empty
- The driver {%s} cannot be found in the path %s. Please ensur
- datasource required not null!
- unknown dbtype:{dbType}
- rm client is not connected. dbkey:{resourceId},clientId:{cli
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/7d9292438452ba5a.
Report an issue: GitHub.