Skip to content

Commit

Permalink
Create SQLExceptionOverride instance when exceptionOverrideClassName …
Browse files Browse the repository at this point in the history
…loaded

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 brettwooldridgeGH-2124
  • Loading branch information
quaff committed Nov 3, 2023
1 parent 58909f0 commit bf7b07c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
27 changes: 22 additions & 5 deletions src/main/java/com/zaxxer/hikari/HikariConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -892,15 +893,31 @@ public void setExceptionOverrideClassName(String exceptionOverrideClassName)
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) {
throw new RuntimeException("Failed to instantiate class " + exceptionOverrideClassName, e);
}
}


/**
* 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 default transaction isolation level. The specified value is the
* constant name from the <code>Connection</code> class, eg.
Expand Down Expand Up @@ -966,15 +983,15 @@ public void copyStateTo(HikariConfig other)
// 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());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/zaxxer/hikari/pool/PoolBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,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;
Expand Down

0 comments on commit bf7b07c

Please sign in to comment.