Protect JMS connection creation against prepareConnection errors

This commit uses a local variable for the creation of a new JMS
Connection so that a rare failure in prepareConnection(...) does not
leave the connection field in a partially initialized state.

If such a JMSException occurs, the intermediary connection is closed.
This commit further defends against close() failures at that point,
by logging the close exception at DEBUG level. As a result, the original
JMSException is always re-thrown.

Closes gh-29116
See gh-29115
This commit is contained in:
Radek Kraus
2023-02-28 16:10:05 +01:00
committed by GitHub
parent b1cf832c28
commit 4cc02fe3bc
2 changed files with 96 additions and 2 deletions

View File

@@ -346,8 +346,26 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
if (this.connection != null) {
closeConnection(this.connection);
}
this.connection = doCreateConnection();
prepareConnection(this.connection);
// Create new (method local) connection, which is later assigned to instance connection
// - prevention to hold instance connection without exception listener, in case when
// some subsequent methods (after creation of connection) throws JMSException
Connection con = doCreateConnection();
try {
prepareConnection(con);
this.connection = con;
}
catch (JMSException ex) {
// Attempt to close new (not used) connection to release possible resources
try {
con.close();
}
catch(Throwable th) {
if (logger.isDebugEnabled()) {
logger.debug("Could not close newly obtained JMS Connection that failed to prepare", th);
}
}
throw ex;
}
if (this.startedCount > 0) {
this.connection.start();
}