@@ -74,6 +74,7 @@ public class HikariConfig implements HikariConfigMXBean
7474 private long initializationFailTimeout ;
7575 private String connectionInitSql ;
7676 private String connectionTestQuery ;
77+ private String credentialsProviderClassName ;
7778 private String dataSourceClassName ;
7879 private String dataSourceJndiName ;
7980 private String driverClassName ;
@@ -88,6 +89,7 @@ public class HikariConfig implements HikariConfigMXBean
8889 private boolean isIsolateInternalQueries ;
8990 private boolean isRegisterMbeans ;
9091 private boolean isAllowPoolSuspension ;
92+ private HikariCredentialsProvider credentialsProvider ;
9193 private DataSource dataSource ;
9294 private Properties dataSourceProperties ;
9395 private ThreadFactory threadFactory ;
@@ -500,26 +502,12 @@ public void setDriverClassName(String driverClassName)
500502 {
501503 checkIfSealed ();
502504
503- var driverClass = attemptFromContextLoader (driverClassName );
504505 try {
505- if (driverClass == null ) {
506- driverClass = this .getClass ().getClassLoader ().loadClass (driverClassName );
507- LOGGER .debug ("Driver class {} found in the HikariConfig class classloader {}" , driverClassName , this .getClass ().getClassLoader ());
508- }
509- } catch (ClassNotFoundException e ) {
510- LOGGER .error ("Failed to load driver class {} from HikariConfig class classloader {}" , driverClassName , this .getClass ().getClassLoader ());
511- }
512-
513- if (driverClass == null ) {
514- throw new RuntimeException ("Failed to load driver class " + driverClassName + " in either of HikariConfig class loader or Thread context classloader" );
515- }
516-
517- try {
518- driverClass .getConstructor ().newInstance ();
506+ createInstance (driverClassName , java .sql .Driver .class );
519507 this .driverClassName = driverClassName ;
520508 }
521509 catch (Exception e ) {
522- throw new RuntimeException ("Failed to instantiate class " + driverClassName , e );
510+ throw new RuntimeException ("Failed to load driver class " + driverClassName , e );
523511 }
524512 }
525513
@@ -879,6 +867,59 @@ public void setSchema(String schema)
879867 this .schema = schema ;
880868 }
881869
870+ /**
871+ * Get the class name of the {@link HikariCredentialsProvider} that will be used to get credentials at runtime.
872+ *
873+ * @return the class name of the credentials provider
874+ * @see HikariCredentialsProvider
875+ */
876+ public String getCredentialsProviderClassName ()
877+ {
878+ return credentialsProviderClassName ;
879+ }
880+
881+ /**
882+ * Set the class name of the {@link HikariCredentialsProvider} that will be used to get credentials at runtime. Use this method
883+ * or provide a {@link HikariCredentialsProvider} instance via the {@link #setCredentialsProvider(HikariCredentialsProvider)} method.
884+ *
885+ * @param credentialsProviderClassName the class name of the credentials provider
886+ * @see HikariCredentialsProvider
887+ */
888+ public void setCredentialsProviderClassName (String credentialsProviderClassName ) {
889+ checkIfSealed ();
890+
891+ try {
892+ this .credentialsProvider = createInstance (credentialsProviderClassName , HikariCredentialsProvider .class );
893+ this .exceptionOverrideClassName = credentialsProviderClassName ;
894+ }
895+ catch (Exception e ) {
896+ throw new RuntimeException ("Failed to instantiate class " + credentialsProviderClassName , e );
897+ }
898+ }
899+
900+ /**
901+ * Get the {@link HikariCredentialsProvider} instance created by {@link #setCredentialsProviderClassName(String)} or specified by
902+ * {@link #setCredentialsProvider(HikariCredentialsProvider)}.
903+ *
904+ * @return the HikariCredentialsProvider instance, or null
905+ * @see HikariCredentialsProvider
906+ */
907+ public HikariCredentialsProvider getCredentialsProvider () {
908+ return credentialsProvider ;
909+ }
910+
911+ /**
912+ * Set a user supplied {@link HikariCredentialsProvider} instance. If this method is used, then the {@link #setCredentialsProviderClassName(String)}
913+ * method should not be used. The {@link HikariCredentialsProvider} instance will be used to get credentials at runtime.
914+ *
915+ * @param credentialsProvider a user supplied HikariCredentialsProvider instance
916+ * @see HikariCredentialsProvider
917+ */
918+ public void setCredentialsProvider (HikariCredentialsProvider credentialsProvider ) {
919+ checkIfSealed ();
920+ this .credentialsProvider = credentialsProvider ;
921+ }
922+
882923 /**
883924 * Get the user supplied SQLExceptionOverride class name.
884925 *
@@ -900,38 +941,20 @@ public void setExceptionOverrideClassName(String exceptionOverrideClassName)
900941 {
901942 checkIfSealed ();
902943
903- var overrideClass = attemptFromContextLoader (exceptionOverrideClassName );
904- try {
905- if (overrideClass == null ) {
906- overrideClass = this .getClass ().getClassLoader ().loadClass (exceptionOverrideClassName );
907- LOGGER .debug ("SQLExceptionOverride class {} found in the HikariConfig class classloader {}" , exceptionOverrideClassName , this .getClass ().getClassLoader ());
908- }
909- } catch (ClassNotFoundException e ) {
910- LOGGER .error ("Failed to load SQLExceptionOverride class {} from HikariConfig class classloader {}" , exceptionOverrideClassName , this .getClass ().getClassLoader ());
911- }
912-
913- if (overrideClass == null ) {
914- throw new RuntimeException ("Failed to load SQLExceptionOverride class " + exceptionOverrideClassName + " in either of HikariConfig class loader or Thread context classloader" );
915- }
916-
917- if (!SQLExceptionOverride .class .isAssignableFrom (overrideClass )) {
918- throw new RuntimeException ("Loaded SQLExceptionOverride class " + exceptionOverrideClassName + " does not implement " + SQLExceptionOverride .class .getName ());
919- }
920-
921944 try {
922- this .exceptionOverride = ( SQLExceptionOverride ) overrideClass . getConstructor (). newInstance ( );
945+ this .exceptionOverride = createInstance ( exceptionOverrideClassName , SQLExceptionOverride . class );
923946 this .exceptionOverrideClassName = exceptionOverrideClassName ;
924947 }
925948 catch (Exception e ) {
926949 throw new RuntimeException ("Failed to instantiate class " + exceptionOverrideClassName , e );
927950 }
928951 }
929952
930-
931953 /**
932- * Get the SQLExceptionOverride instance created by {@link #setExceptionOverrideClassName(String)}.
954+ * Get the SQLExceptionOverride instance created by {@link #setExceptionOverrideClassName(String)} or specified by
955+ * {@link #setExceptionOverride(SQLExceptionOverride)}.
933956 *
934- * @return the SQLExceptionOverride instance, or null if {@link #setExceptionOverrideClassName(String)} is not called
957+ * @return the SQLExceptionOverride instance, or null
935958 * @see SQLExceptionOverride
936959 */
937960 public SQLExceptionOverride getExceptionOverride ()
@@ -1018,22 +1041,6 @@ public void copyStateTo(HikariConfig other)
10181041 // Private methods
10191042 // ***********************************************************************
10201043
1021- private Class <?> attemptFromContextLoader (final String className ) {
1022- final var threadContextClassLoader = Thread .currentThread ().getContextClassLoader ();
1023- if (threadContextClassLoader != null ) {
1024- try {
1025- final var driverClass = threadContextClassLoader .loadClass (className );
1026- LOGGER .debug ("Class {} found in Thread context class loader {}" , className , threadContextClassLoader );
1027- return driverClass ;
1028- } catch (ClassNotFoundException e ) {
1029- LOGGER .debug ("Class {} not found in Thread context class loader {}, trying classloader {}" ,
1030- driverClassName , threadContextClassLoader , this .getClass ().getClassLoader ());
1031- }
1032- }
1033-
1034- return null ;
1035- }
1036-
10371044 @ SuppressWarnings ("StatementWithEmptyBody" )
10381045 public void validate ()
10391046 {
0 commit comments