Don't leak Connections when PoolableConnectionFactory.makeObject() fails
to create a JMX ObjectName.
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 73226f9..9c07a75 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -108,6 +108,9 @@
<action dev="ggregory" type="add" due-to="Gary Gregory">
Replace Exception with SQLException in some method signatures (preserves binary compatibility, not source).
</action>
+ <action dev="ggregory" type="add" due-to="Gary Gregory">
+ Don't leak Connections when PoolableConnectionFactory.makeObject() fails to create a JMX ObjectName.
+ </action>
<!-- UPDATE -->
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">
Bump actions/cache from 2.1.6 to 3.0.4 #147, #176.
diff --git a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
index 68f7928..937c55c 100644
--- a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
@@ -24,6 +24,7 @@
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
+import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
@@ -417,11 +418,11 @@
}
try {
initializeConnection(conn);
- } catch (final SQLException sqle) {
+ } catch (final SQLException e) {
// Make sure the connection is closed
Utils.closeQuietly((AutoCloseable) conn);
// Rethrow original exception so it is visible to caller
- throw sqle;
+ throw e;
}
final long connIndex = connectionIndex.getAndIncrement();
@@ -444,8 +445,7 @@
config.setJmxEnabled(false);
}
final PoolingConnection poolingConn = (PoolingConnection) conn;
- final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> stmtPool = new GenericKeyedObjectPool<>(
- poolingConn, config);
+ final KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> stmtPool = new GenericKeyedObjectPool<>(poolingConn, config);
poolingConn.setStatementPool(stmtPool);
poolingConn.setClearStatementPoolOnReturn(clearStatementPoolOnReturn);
poolingConn.setCacheState(cacheState);
@@ -456,12 +456,16 @@
if (dataSourceJmxObjectName == null) {
connJmxName = null;
} else {
- connJmxName = new ObjectName(
- dataSourceJmxObjectName.toString() + Constants.JMX_CONNECTION_BASE_EXT + connIndex);
+ final String name = dataSourceJmxObjectName.toString() + Constants.JMX_CONNECTION_BASE_EXT + connIndex;
+ try {
+ connJmxName = new ObjectName(name);
+ } catch (MalformedObjectNameException e) {
+ Utils.closeQuietly((AutoCloseable) conn);
+ throw new SQLException(name, e);
+ }
}
- final PoolableConnection pc = new PoolableConnection(conn, pool, connJmxName, disconnectionSqlCodes,
- fastFailValidation);
+ final PoolableConnection pc = new PoolableConnection(conn, pool, connJmxName, disconnectionSqlCodes, fastFailValidation);
pc.setCacheState(cacheState);
return new DefaultPooledObject<>(pc);