better exception message in pool init

This commit is contained in:
Jörg Prante 2025-03-12 16:10:03 +01:00
parent 1ccbaa8d6a
commit 1578483688
2 changed files with 22 additions and 31 deletions

View file

@ -1,3 +1,3 @@
group = org.xbib group = org.xbib
name = database name = database
version = 2.3.2 version = 2.3.3

View file

@ -3,6 +3,7 @@ package org.xbib.jdbc.pool;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.Principal; import java.security.Principal;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
@ -31,7 +32,7 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
private final Mode factoryMode; private final Mode factoryMode;
// these are the sources for connections, that will be used depending on the mode // these are the sources for connections, that will be used depending on the mode
private java.sql.Driver driver; private Driver driver;
private javax.sql.DataSource dataSource; private javax.sql.DataSource dataSource;
private javax.sql.XADataSource xaDataSource; private javax.sql.XADataSource xaDataSource;
private javax.sql.XADataSource xaRecoveryDataSource; private javax.sql.XADataSource xaRecoveryDataSource;
@ -42,7 +43,6 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
public ConnectionFactory(XbibConnectionFactoryConfiguration configuration, XbibDataSourceListener... listeners) { public ConnectionFactory(XbibConnectionFactoryConfiguration configuration, XbibDataSourceListener... listeners) {
this.configuration = configuration; this.configuration = configuration;
this.listeners = listeners; this.listeners = listeners;
factoryMode = Mode.fromClass(configuration.connectionProviderClass()); factoryMode = Mode.fromClass(configuration.connectionProviderClass());
switch (factoryMode) { switch (factoryMode) {
case XA_DATASOURCE: case XA_DATASOURCE:
@ -113,27 +113,25 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
} }
@SuppressWarnings("StringConcatenation") @SuppressWarnings("StringConcatenation")
private java.sql.Driver newDriver() { private Driver newDriver() {
DriverManager.setLoginTimeout((int) configuration.loginTimeout().getSeconds()); DriverManager.setLoginTimeout((int) configuration.loginTimeout().getSeconds());
if (configuration.connectionProviderClass() == null) { if (configuration.connectionProviderClass() == null) {
try { try {
return driver = DriverManager.getDriver(configuration.jdbcUrl()); return driver = DriverManager.getDriver(configuration.jdbcUrl());
} catch (SQLException sql) { } catch (SQLException e) {
throw new RuntimeException("Unable to get java.sql.Driver from DriverManager", sql); throw new RuntimeException("Unable to get Driver for URL '" + configuration.jdbcUrl() + "' from DriverManager: " + e.getMessage(), e);
} }
} else { } else {
try { try {
driver = configuration.connectionProviderClass().asSubclass(java.sql.Driver.class).getDeclaredConstructor().newInstance(); driver = configuration.connectionProviderClass().asSubclass(Driver.class).getDeclaredConstructor().newInstance();
if (!driver.acceptsURL(configuration.jdbcUrl())) { if (!driver.acceptsURL(configuration.jdbcUrl())) {
fireOnWarning(listeners, "Driver does not support the provided URL: " + configuration.jdbcUrl()); fireOnWarning(listeners, "Driver does not support the provided URL: " + configuration.jdbcUrl());
} }
return driver; return driver;
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
NoSuchMethodException e) { throw new RuntimeException("Unable to instantiate Driver: " + e.getMessage(), e);
throw new RuntimeException("Unable to instantiate java.sql.Driver", e);
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException("Unable to verify that the java.sql.Driver supports the provided URL", e); throw new RuntimeException("Unable to verify that the Driver supports the provided URL: " + e.getMessage(), e);
} }
} }
} }
@ -213,30 +211,27 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
return EMPTY_PROPERTIES; return EMPTY_PROPERTIES;
} }
// --- //
public XAConnection createConnection() throws SQLException { public XAConnection createConnection() throws SQLException {
switch (factoryMode) { return switch (factoryMode) {
case DRIVER: case DRIVER ->
return new XAConnectionAdaptor(connectionSetup(driver.connect(configuration.jdbcUrl(), jdbcProperties()))); new XAConnectionAdaptor(connectionSetup(driver.connect(configuration.jdbcUrl(), jdbcProperties())));
case DATASOURCE: case DATASOURCE -> {
injectJdbcProperties(dataSource, securityProperties(configuration.principal(), configuration.credentials())); injectJdbcProperties(dataSource, securityProperties(configuration.principal(), configuration.credentials()));
return new XAConnectionAdaptor(connectionSetup(dataSource.getConnection())); yield new XAConnectionAdaptor(connectionSetup(dataSource.getConnection()));
case XA_DATASOURCE: }
case XA_DATASOURCE -> {
injectJdbcProperties(xaDataSource, securityProperties(configuration.principal(), configuration.credentials())); injectJdbcProperties(xaDataSource, securityProperties(configuration.principal(), configuration.credentials()));
return xaConnectionSetup(xaDataSource.getXAConnection()); yield xaConnectionSetup(xaDataSource.getXAConnection());
default: }
throw new SQLException("Unknown connection factory mode"); };
}
} }
@SuppressWarnings("MagicConstant") @SuppressWarnings("MagicConstant")
private Connection connectionSetup(Connection connection) throws SQLException { private Connection connectionSetup(Connection connection) throws SQLException {
if (connection == null) { if (connection == null) {
// AG-90: Driver can return null if the URL is not supported (see java.sql.Driver#connect() documentation) // AG-90: Driver can return null if the URL is not supported (see Driver#connect() documentation)
throw new SQLException("Driver does not support the provided URL: " + configuration.jdbcUrl()); throw new SQLException("Driver does not support the provided URL: " + configuration.jdbcUrl());
} }
connection.setAutoCommit(configuration.autoCommit()); connection.setAutoCommit(configuration.autoCommit());
if (configuration.jdbcTransactionIsolation().isDefined()) { if (configuration.jdbcTransactionIsolation().isDefined()) {
connection.setTransactionIsolation(configuration.jdbcTransactionIsolation().level()); connection.setTransactionIsolation(configuration.jdbcTransactionIsolation().level());
@ -263,8 +258,6 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
return xaConnection; return xaConnection;
} }
// --- //
public boolean hasRecoveryCredentials() { public boolean hasRecoveryCredentials() {
return configuration.recoveryPrincipal() != null || (configuration.recoveryCredentials() != null && !configuration.recoveryCredentials().isEmpty()); return configuration.recoveryPrincipal() != null || (configuration.recoveryCredentials() != null && !configuration.recoveryCredentials().isEmpty());
} }
@ -288,8 +281,6 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
throw new SQLException("Recovery connections are only available for XADataSource"); throw new SQLException("Recovery connections are only available for XADataSource");
} }
// --- //
private enum Mode { private enum Mode {
DRIVER, DATASOURCE, XA_DATASOURCE; DRIVER, DATASOURCE, XA_DATASOURCE;
@ -302,7 +293,7 @@ public final class ConnectionFactory implements ResourceRecoveryFactory {
return XA_DATASOURCE; return XA_DATASOURCE;
} else if (javax.sql.DataSource.class.isAssignableFrom(providerClass)) { } else if (javax.sql.DataSource.class.isAssignableFrom(providerClass)) {
return DATASOURCE; return DATASOURCE;
} else if (java.sql.Driver.class.isAssignableFrom(providerClass)) { } else if (Driver.class.isAssignableFrom(providerClass)) {
return DRIVER; return DRIVER;
} else { } else {
throw new IllegalArgumentException("Unable to create ConnectionFactory from providerClass " + providerClass.getName()); throw new IllegalArgumentException("Unable to create ConnectionFactory from providerClass " + providerClass.getName());