{"record":{"id":"09cc4ebffe3db320","repo":"mybatis/mybatis-3","slug":"error-setting-driver-on-unpooleddatasource","errorCode":null,"errorMessage":"Error setting driver on UnpooledDataSource.","messagePattern":"Error setting driver on UnpooledDataSource\\.","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"critical","filePath":"src/main/java/org/apache/ibatis/datasource/unpooled/UnpooledDataSource.java","lineNumber":251,"sourceCode":"  private void initializeDriver() throws SQLException {\n    try {\n      registeredDrivers.computeIfAbsent(driver, x -> {\n        Class<?> driverType;\n        try {\n          if (driverClassLoader != null) {\n            driverType = Class.forName(x, true, driverClassLoader);\n          } else {\n            driverType = Resources.classForName(x);\n          }\n          Driver driverInstance = (Driver) driverType.getDeclaredConstructor().newInstance();\n          DriverManager.registerDriver(new DriverProxy(driverInstance));\n          return driverInstance;\n        } catch (Exception e) {\n          throw new RuntimeException(\"Error setting driver on UnpooledDataSource.\", e);\n        }\n      });\n    } catch (RuntimeException re) {\n      throw new SQLException(\"Error setting driver on UnpooledDataSource.\", re.getCause());\n    }\n  }\n\n  private void configureConnection(Connection conn) throws SQLException {\n    if (defaultNetworkTimeout != null) {\n      conn.setNetworkTimeout(Executors.newSingleThreadExecutor(), defaultNetworkTimeout);\n    }\n    if (autoCommit != null && autoCommit != conn.getAutoCommit()) {\n      conn.setAutoCommit(autoCommit);\n    }\n    if (defaultTransactionIsolationLevel != null) {\n      conn.setTransactionIsolation(defaultTransactionIsolationLevel);\n    }\n  }\n\n  private static class DriverProxy implements Driver {\n    private final Driver driver;\n","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/datasource/unpooled/UnpooledDataSource.java#L233-L269","documentation":"UnpooledDataSource calms driver initialization into a memoized block: it loads the class named by the 'driver' property (via the driverClassLoader if set), instantiates it, registers a DriverProxy, and returns the instance. Any failure (ClassNotFoundException, instantiation error, security exception, registerDriver failure) is wrapped in RuntimeException, then rethrown as SQLException 'Error setting driver on UnpooledDataSource.' with the original cause attached. The actual reason is in the cause chain.","triggerScenarios":"Setting <property name=\"driver\" value=\"...\"/> to a class name not on the classpath (typo, missing JDBC driver jar, wrong artifact for DB version); driver class present but lacking a public no-arg constructor; classloader isolation (driver jar in a child classloader, e.g., some app servers/plugins) with no driverClassLoader configured; SecurityManager blocking instantiation or registration.","commonSituations":"Missing JDBC driver dependency (e.g., forgot mysql-connector-j or postgresql in pom.xml); upgrading a DB and driver class rename (e.g., com.mysql.jdbc.Driver -> com.mysql.cj.jdbc.Driver); shading/relocating the driver class; running in OSGi or complex classloader layouts.","solutions":["Inspect getCause() of the SQLException: ClassNotFoundException names the exact missing/typo'd class","Add or fix the JDBC driver dependency and use the correct current class name (e.g., com.mysql.cj.jdbc.Driver for Connector/J 8+)","Verify with Class.forName(\"your.Driver\") in the same runtime/classloader that runs MyBatis","In classloader-restricted environments, supply a driverClassLoader via UnpooledDataSource.setDriverClassLoader (e.g., thread context classloader)","On JDBC 4+ drivers you may omit the driver property entirely — DriverManager auto-discovers drivers via META-INF/services"],"exampleFix":"<!-- before -->\n<property name=\"driver\" value=\"com.mysql.jdbc.Driver\"/> <!-- removed in Connector/J 8 -->\n\n<!-- after -->\n<property name=\"driver\" value=\"com.mysql.cj.jdbc.Driver\"/>\n<!-- or omit 'driver' entirely on JDBC4+ -->","handlingStrategy":"validation","validationCode":"// Verify the driver class loads in the runtime classloader before building the config:\nString driver = \"com.mysql.cj.jdbc.Driver\";\nClass.forName(driver, true, Thread.currentThread().getContextClassLoader());","typeGuard":null,"tryCatchPattern":"try {\n  dataSource.getConnection();\n} catch (SQLException e) {\n  if (\"Error setting driver on UnpooledDataSource.\".equals(e.getMessage())) {\n    Throwable c = e.getCause(); // ClassNotFoundException etc. names the problem\n    throw new IllegalStateException(\"JDBC driver misconfigured: \" + c, e);\n  }\n  throw e;\n}","preventionTips":["Pin the JDBC driver artifact in build files and verify the class name for the driver version in use","On JDBC 4+, omit the driver property and let DriverManager auto-discover","Add a startup health check that opens one connection before serving traffic"],"tags":["mybatis","jdbc-driver","classpath","configuration","classloader"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}