Create SQLExceptionOverride instance when exceptionOverrideClassName loaded (#2133)

Before this commit, exceptionOverrideClass may be loaded by different ClassLoader, and two instances are created but only the latter one is used. This commit make sure the class will only loaded once and only one instance is created.

Fix GH-2124
Fix GH-2171
pull/2241/head
Yanming Zhou 4 months ago committed by GitHub
parent 82c82adfda
commit 8053e39996
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -80,6 +80,7 @@ public class HikariConfig implements HikariConfigMXBean
private String dataSourceJndiName;
private String driverClassName;
private String exceptionOverrideClassName;
private SQLExceptionOverride exceptionOverride;
private String jdbcUrl;
private String poolName;
private String schema;
@ -913,8 +914,12 @@ public class HikariConfig implements HikariConfigMXBean
throw new RuntimeException("Failed to load SQLExceptionOverride class " + exceptionOverrideClassName + " in either of HikariConfig class loader or Thread context classloader");
}
if (!SQLExceptionOverride.class.isAssignableFrom(overrideClass)) {
throw new RuntimeException("Loaded SQLExceptionOverride class " + exceptionOverrideClassName + " does not implement " + SQLExceptionOverride.class.getName());
}
try {
overrideClass.getConstructor().newInstance();
this.exceptionOverride = (SQLExceptionOverride) overrideClass.getConstructor().newInstance();
this.exceptionOverrideClassName = exceptionOverrideClassName;
}
catch (Exception e) {
@ -922,6 +927,29 @@ public class HikariConfig implements HikariConfigMXBean
}
}
/**
* Get the SQLExceptionOverride instance created by {@link #setExceptionOverrideClassName(String)}.
*
* @return the SQLExceptionOverride instance, or null if {@link #setExceptionOverrideClassName(String)} is not called
* @see SQLExceptionOverride
*/
public SQLExceptionOverride getExceptionOverride()
{
return this.exceptionOverride;
}
/**
* Set the user supplied SQLExceptionOverride instance.
*
* @param exceptionOverride the user supplied SQLExceptionOverride instance
* @see SQLExceptionOverride
*/
public void setExceptionOverride(SQLExceptionOverride exceptionOverride) {
checkIfSealed();
this.exceptionOverride = exceptionOverride;
}
/**
* Set the default transaction isolation level. The specified value is the
* constant name from the <code>Connection</code> class, eg.
@ -990,15 +1018,15 @@ public class HikariConfig implements HikariConfigMXBean
// Private methods
// ***********************************************************************
private Class<?> attemptFromContextLoader(final String driverClassName) {
private Class<?> attemptFromContextLoader(final String className) {
final var threadContextClassLoader = Thread.currentThread().getContextClassLoader();
if (threadContextClassLoader != null) {
try {
final var driverClass = threadContextClassLoader.loadClass(driverClassName);
LOGGER.debug("Driver class {} found in Thread context class loader {}", driverClassName, threadContextClassLoader);
final var driverClass = threadContextClassLoader.loadClass(className);
LOGGER.debug("Class {} found in Thread context class loader {}", className, threadContextClassLoader);
return driverClass;
} catch (ClassNotFoundException e) {
LOGGER.debug("Driver class {} not found in Thread context class loader {}, trying classloader {}",
LOGGER.debug("Class {} not found in Thread context class loader {}, trying classloader {}",
driverClassName, threadContextClassLoader, this.getClass().getClassLoader());
}
}

@ -98,7 +98,7 @@ abstract class PoolBase
this.schema = config.getSchema();
this.isReadOnly = config.isReadOnly();
this.isAutoCommit = config.isAutoCommit();
this.exceptionOverride = UtilityElf.createInstance(config.getExceptionOverrideClassName(), SQLExceptionOverride.class);
this.exceptionOverride = config.getExceptionOverride();
this.transactionIsolation = UtilityElf.getTransactionIsolation(config.getTransactionIsolation());
this.isQueryTimeoutSupported = UNINITIALIZED;

Loading…
Cancel
Save