Uploaded image for project: 'ActiveMQ'
  1. ActiveMQ
  2. AMQ-5258

Connection reference leak in PooledConnectionFactory leading to expired connections stuck in the pool

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.9.1, 5.10.0
    • Fix Version/s: 5.10.1, 5.11.0
    • Component/s: Pool
    • Labels:
      None

      Description

      org.apache.activemq.jms.pool.PooledConnectionFactory creates a connection on startup without giving it back to the pool:

          public void start() {
              LOG.debug("Staring the PooledConnectionFactory: create on start = {}", isCreateConnectionOnStartup());
              stopped.set(false);
              if (isCreateConnectionOnStartup()) {
                  try {
                      // warm the pool by creating a connection during startup
                      createConnection();
                  } catch (JMSException e) {
                      LOG.warn("Create pooled connection during start failed. This exception will be ignored.", e);
                  }
              }
          }
      

      So no close() method of PooledConnection is called and so no decrementReferenceCount is called on ConnectionPool. So referenceCount never becomes 0.
      Later on if an exception occurs and hasExpired of ConnectionPool is set to true, the connection will not be closed since expiredCheck() method of ConnectionPool always compares referenceCount with 0 and does close() only if it is 0.

      So we have a dead ConnectionPool instance and all usages result in "XXX closed" errors.

      The fix would be to add call to close() just after doing createConnection() in PooledConnectionFactory#start() to make referenceCount go to 0. Something like this:

          public void start() {
              LOG.debug("Staring the PooledConnectionFactory: create on start = {}", isCreateConnectionOnStartup());
              stopped.set(false);
              if (isCreateConnectionOnStartup()) {
                  try {
                      // warm the pool by creating a connection during startup
                      createConnection().close(); // <--- makes sure referenceCount goes to 0
                  } catch (JMSException e) {
                      LOG.warn("Create pooled connection during start failed. This exception will be ignored.", e);
                  }
              }
          }
      

        Attachments

          Activity

            People

            • Assignee:
              tabish Timothy A. Bish
              Reporter:
              barlabanov Sergiy Barlabanov
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: