brettwooldridge / HikariCP

光 HikariCP・A solid, high-performance, JDBC connection pool at last.
Apache License 2.0
19.91k stars 2.92k forks source link

ClassNotFoundException using SQLExceptionOverride #2124

Closed YotillaAntoni closed 1 week ago

YotillaAntoni commented 11 months ago

We run into a similar issue to https://github.com/brettwooldridge/HikariCP/issues/1489 so we were using the SQLExceptionOverride mechanism to avoid the eviction of a connection in some circumstances

But in some scenarios a ClassNotFoundException is thrown when creating a HikariDataSource after having defined a valid HikariConfig setting an exceptionOverrrideClassName

When the class name of the override handler is set via HikariConfig.setExceptionOverrideClassName to validate the input a loadClass is attempted using the Thread Context ClassLoader. (HikariConfig line 875)

When this validated configuration is used to create a DataSource, and the PoolBase is instantiated, it attemps to load the class name for the exceptionOverrride field, using the UtilityElf.createInstance(...) method.

But the UtilityElf doesn't use the Thread Context ClassLoader, but the ClassLoader used to load itself (UtilityElf line 93):

var loaded = UtilityElf.class.getClassLoader().loadClass(className);

When the HikariCP library is at a higher class loader, like a application container ClassLoader, and the application using it is at "lower" class loader, like a typical WebApp ClassLoader for a WAR, it's not possible to use an application class as SQLExceptionOverride.

Setting the className in the HikariCofig will work, because to check the validity of the className it uses the Thread Context Class Loader, but after that the instantiation of PoolBase will fail

IMO the solution should be change UtilityElf line 93 for:

var loaded = Thread.currentThread().getContextClassLoader().loadClass(className);

In case this isn't possible, for whatever reason, then the check on HikariConfig.setExceptionOverrideClassName line 875

var overrideClass = attemptFromContextLoader(exceptionOverrideClassName);

should be changed, to attempt a load from the class loader obtained using HikariConfig.class.getClassLoader() for example, so at least the behaviour is consistent, and you would get a ClassNotFoundException when creating the HikariConfig

lfbayer commented 11 months ago

If someone provides a pull request with a fix and a unit test, I will be happy to merge it.

quaff commented 11 months ago

If someone provides a pull request with a fix and a unit test, I will be happy to merge it.

@lfbayer I created https://github.com/brettwooldridge/HikariCP/pull/2133.

YotillaAntoni commented 2 months ago

Thanks @quaff . Any chance this gets merged?

quaff commented 2 months ago

Thanks @quaff . Any chance this gets merged?

I don't know, It seems this project is not active.