5 Replies Latest reply on Oct 19, 2005 4:44 AM by Dan Salt

    Connection Pooling with NoTx test adapter

    Dan Salt Newbie

      Hi,

      I'm currently writing an example JCA Resource Adapter to evaluate the work involved and the benefits, etc of using JCA. Thanks to many articles (including posts on this and other forums) I have been able to create, deploy and invoke a dummy operation via a Servlet against my own Non-Transactional Resource Adapter. For the actual ResourceAdapter implementation, I am using the DummyResourceAdapter provided by JBossJCA.

      But (!) I am having problems getting connection pooling to work properly. I have (arbitrarily) set the MaxPool to 5 to test connection pooling. I am calling close() from my connection at the end of each call to the servlet. The implementation of this simply releases the reference to the ManagedConnection implementation. However, when I try to call the servlet 6 times in succession, on the 6th it throws an exception claiming there are no available connections. I have read the posts regarding this message, but can't see how or why I would be leaking connections.

      Have I implemented all that I need to, in order that the ConnectionManager will pool (and more importantly re-use) my connections?

      I can attach code if required, thought I would omit this to start with as it might be a trivially stupid mistake I'm making! :)

      Cheers,
      Dan

        • 1. Re: Connection Pooling with NoTx test adapter
          Scott Stark Master

          Debugging via trace logging or a debugger is needed to understand how your code interacts with the pooling layer. Read the "READ THIS FIRST" posting for more info.

          • 2. Re: Connection Pooling with NoTx test adapter
            Dan Salt Newbie

            Hi, thanks for the advice.

            I had read the "READ THIS FIRST", and turned on the trace, but stupidly was looking for the trace output in the wrong place. Apologies.

            The trace log doesn't seem to indicate that any connections are being returned to the pool. I am calling close() on the Connection object, which in turn frees up the reference to the ManagedConnection. Should I be doing something else? Do I need to physically notify the ConnectionManager in some way, or is that done implicitly through the Connection Management layer provided by JBoss?

            Cheers,
            Dan.


            2005-10-17 11:11:44,290 INFO [STDOUT] >> FSConnectionFactory - getConnection(spec)
            2005-10-17 11:11:44,300 DEBUG [org.jboss.resource.connectionmanager.IdleRemover] internalRegisterPool: registering pool with interval 900000 old interval: 9223372036854775807
            2005-10-17 11:11:44,300 DEBUG [org.jboss.resource.connectionmanager.IdleRemover] internalRegisterPool: about to notify thread: old next: 1129544354300, new next: 1129544354300
            2005-10-17 11:11:44,310 INFO [STDOUT] >> NEW FSManagedConnection (0)
            2005-10-17 11:11:44,310 TRACE [org.jboss.resource.connectionmanager.JBossManagedConnectionPool] supplying new ManagedConnection: org.jboss.resource.connectionmanager.NoTxConnectionManager$NoTxConnectionEventListener@9b46a8[state=NORMAL mc=dan.test.spi.FSManagedConnection@3bfb66 handles=0 lastUse=1129543904310 permit=false trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool@1f62649 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@14b8cdc]
            2005-10-17 11:11:44,310 TRACE [org.jboss.resource.connectionmanager.JBossManagedConnectionPool] Getting connection from pool org.jboss.resource.connectionmanager.NoTxConnectionManager$NoTxConnectionEventListener@9b46a8[state=NORMAL mc=dan.test.spi.FSManagedConnection@3bfb66 handles=0 lastUse=1129543904310 permit=true trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool@1f62649 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@14b8cdc] [InUse/Available/Max]: [1/4/5]

            [SNIP - 3 MORE TIMES THE SAME (2/5, 3/5, 4/5) ]

            2005-10-17 11:12:51,607 INFO [STDOUT] >> FSConnectionFactory - getConnection(spec)
            2005-10-17 11:12:51,607 INFO [STDOUT] >> NEW FSManagedConnection (4)
            2005-10-17 11:12:51,607 TRACE [org.jboss.resource.connectionmanager.JBossManagedConnectionPool] supplying new ManagedConnection: org.jboss.resource.connectionmanager.NoTxConnectionManager$NoTxConnectionEventListener@1da692f[state=NORMAL mc=dan.test.spi.FSManagedConnection@2fbdd2 handles=0 lastUse=1129543971607 permit=false trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool@1f62649 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@14b8cdc]
            2005-10-17 11:12:51,607 TRACE [org.jboss.resource.connectionmanager.JBossManagedConnectionPool] Getting connection from pool org.jboss.resource.connectionmanager.NoTxConnectionManager$NoTxConnectionEventListener@1da692f[state=NORMAL mc=dan.test.spi.FSManagedConnection@2fbdd2 handles=0 lastUse=1129543971607 permit=true trackByTx=false mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool@1f62649 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@14b8cdc] [InUse/Available/Max]: [5/0/5]


            2005-10-17 11:12:55,542 INFO [STDOUT] >> FSConnectionFactory - getConnection(spec)
            2005-10-17 11:13:25,575 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/JCAWebTest].[JCATestServlet]] Servlet.service() for servlet JCATestServlet threw exception
            javax.resource.ResourceException: No ManagedConnections available within configured blocking timeout ( 30000 [ms] )
            at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.getConnection(InternalManagedConnectionPool.java:246)
            at org.jboss.resource.connectionmanager.JBossManagedConnectionPool$BasePool.getConnection(JBossManagedConnectionPool.java:534)


            [SNIP - continuation of stack track...]

            • 3. Re: Connection Pooling with NoTx test adapter
              Dan Salt Newbie

              I've now solved the problem.

              It was, as I suspected, a stupid beginners problem. I eventually realized that the JBoss ConnectionManager needs to receive the CONNECTION_CLOSED event sent from the ManagedConnection, together with a handle to the Connection. Once I had figured out the interactions between these layers the answer was rather obvious - just couldn't initially see the Woods for the Trees :)

              Thanks,
              Dan

              • 4. Re: Connection Pooling with NoTx test adapter
                Lamar Channell Newbie

                Dan,

                I'm having the same problem. Could you post your sample code on how you fixed the problem?

                Thanks,
                Lamar

                • 5. Re: Connection Pooling with NoTx test adapter
                  Dan Salt Newbie

                  Sure, no problem. The code needs to be inserted in your ManagedConnection implementation. You need an instance variable to track the "listeners" on the connection. As I understand it, when JBoss allocates the connection using the ConnectionManager, it calls the "addConnectionEventListener" method in your ManagedConnection class, adding the Connection Manager as a ConnectionEventListener. When you close the client connection, your code should call an method (I called mine "disconnectConnection") in the Managed Connection that notifies any listeners that the connection has closed. When the ConnectionManager receives this notification, it returns the ManagedConnection to the pool.

                  So, for example:

                  private ArrayList _listeners = new ArrayList();
                  public void addConnectionEventListener(ConnectionEventListener arg0) {
                   _listeners.add(arg0);
                  }
                  public void removeConnectionEventListener(ConnectionEventListener arg0) {
                   _listeners.remove(arg0);
                  }
                  
                  /**
                   * Called by the CCI Connection to notify the Managed Connection that is has finished.
                   * This should post the correct event
                   * to listeners on this managed connection (namely the AppServer's ConnectionManager).
                   * @param arg0 The CCI Connection being disconnected
                   */
                  public void disconnectConnection(Connection arg0) {
                   // Create the disconnection event
                   ConnectionEvent cev = new ConnectionEvent(this,ConnectionEvent.CONNECTION_CLOSED);
                   // Set the handle to the actual CCI connection being removed
                   cev.setConnectionHandle(arg0);
                  
                   // Send the event to the listeners
                   for(int i = 0; i < _listeners.size(); i++) {
                   ConnectionEventListener l = (ConnectionEventListener)_listeners.get(i);
                   l.connectionClosed(cev);
                   }
                  }


                  And then in the actual Client Connection class:

                  protected FSManagedConnection m_mc;
                  public void close() throws ResourceException {
                   FSManagedConnection mc = m_mc;
                   m_mc = null;
                   mc.disconnectConnection(this);
                  }


                  Hope this helps,
                  Dan.