Yep, my code is based on the J2EE tutorial example. Can you confirm that the coding practice is indeed OK (code and stack trace below)?
If this can be considered a bug, it is a case of the leak detector not being smart enough to tell that the connection is still in use. I suspect that a colleague who setup the server may have left leak detection turned on in the sun-resources.xml/ant script:
connection-leak-reclaim="false" [b]connection-leak-timeout-in-seconds="60"[/b] [i](should be 0)[/i]
public class HubToFabRouterSBean implements HubToFabRouterLocal
{
@Resource(name = "jms/HubFactoryRef")
private ConnectionFactory connectionFactory;
@Resource
private SessionContext sessionContext;
private Connection connection = null;
private static final int NUM_QUEUES = 2;
public static final String WORK_ORDER_DEST_SEA01 = "jms/HubToFabSEA01Queue";
public static final String WORK_ORDER_DEST_NYC01 = "jms/HubToFabNYC01Queue";
@Resource(mappedName = WORK_ORDER_DEST_SEA01)
private Queue queueSEA01;
@Resource(mappedName = WORK_ORDER_DEST_NYC01)
private Queue queueNYC01;
private Map<String, Queue> queueMap;
/**
* Friendly name of the server sending messages;
* this value will be inserted into the Linx request XML.
*/
@Resource(name = "senderName")
private String senderName;
/**
* Creates the connection.
*/
[b] @PostConstruct
public void makeConnection()[/b]
{
try
{
[b]connection = connectionFactory.createConnection();[/b] }
catch (Throwable ex)
{
logger.log(Level.SEVERE, "Unable to get JMS connection.", ex);
}
// Create a hash map for queue name validation.
queueMap = new HashMap<String, Queue>(NUM_QUEUES);
queueMap.put(WORK_ORDER_DEST_SEA01, queueSEA01);
queueMap.put(WORK_ORDER_DEST_NYC01, queueNYC01);
}
[b] public Map<String, String> sendAll(String messageText, long tranId)
{[/b]
Session session = null;
MessageProducer producer = null;
TextMessage message = null;
// Map of sent queue-name/message ID pairs.
Map<String, String> sentMessageMap = new HashMap<String, String>(NUM_QUEUES);
try
{
// Within an EJB, transactions are container managed.
// If an exception is thrown, the session won't be committed and
// none of the messages will be delivered.
session = connection.createSession(true, 0);
// Send a message to each queue.
Set<Entry<String, Queue>> entrySet = queueMap.entrySet();
for (Entry<String, Queue> entry : entrySet)
{
Queue queue = entry.getValue();
producer = session.createProducer(queue);
message = session.createTextMessage();
message.setText(messageText);
producer.send(message);
logger.logJMS(Level.FINE, "JMS message sent from EJB " + this.getClass().getSimpleName() + ".", message);
sentMessageMap.put(entry.getKey(), message.getJMSMessageID());
}
return sentMessageMap;
}
catch(Throwable ex)
{
// Transaction is automatically rolled-back when the container gets the exception.
logger.logJMS(Level.SEVERE, ex.getMessage(), message, ex);
// Throw a runtime exception to roll-back the session's transaction.
throw new MessageNotSentException(queueNames, ex);
}
finally
{
try
{
session.close();
}
catch (Throwable ex)
{
logger.log(Level.SEVERE, "Error closing JMS session.", ex);
}
}
}
/**
* Closes the connection.
*/
[b] @PreDestroy
public void endConnection()
{[/b] try
{
[b]connection.close();[/b]
}
catch (Throwable ex)
{
logger.log(Level.SEVERE, "Error closing JMS connection.", ex);
}
}
}
[#|2008-05-21T14:10:15.639-0700|WARNING|sun-appserver9.1|javax.enterprise.resource.resourceadapter|_ThreadID=23;_ThreadName=Timer-32;ConnectionPoolName=jms/HubPool;_RequestID=85a25449-e617-43a3-8a4b-76f4b3a4002d;|[b]A potential connection leak detected for connection pool jms/HubPool[/b]. The stack trace of the thread is provided below :
com.sun.enterprise.resource.AbstractResourcePool.setResourceStateToBusy(AbstractResourcePool.java:301)
com.sun.enterprise.resource.AbstractResourcePool.getResourceFromPool(AbstractResourcePool.java:778)
com.sun.enterprise.resource.AbstractResourcePool.getUnenlistedResource(AbstractResourcePool.java:652)
com.sun.enterprise.resource.AbstractResourcePool.internalGetResource(AbstractResourcePool.java:594)
com.sun.enterprise.resource.AbstractResourcePool.getResource(AbstractResourcePool.java:443)
com.sun.enterprise.resource.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:248)
com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:176)
com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:327)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:235)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:158)
com.sun.messaging.jms.ra.ConnectionFactoryAdapter._allocateConnection(ConnectionFactoryAdapter.java:179)
com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:166)
com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:148)
com.ilmn.dam.hub.jms.HubToFabRouterSBean.makeConnection(HubToFabRouterSBean.java:86)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
com.sun.ejb.containers.interceptors.BeanCallbackInterceptor.intercept(InterceptorManager.java:728)
com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext(InterceptorManager.java:517)
com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:221)
com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:563)
com.sun.ejb.containers.StatelessSessionContainer.access$100(StatelessSessionContainer.java:111)
com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:772)
com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:199)
com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:486)
com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:1675)
com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1229)
com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:195)
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:127)
$Proxy82.sendAll(Unknown Source)
com.ilmn.hub.servlet.FabRouterDelegate.sendAll(FabRouterDelegate.java:103)
...
[Message sent by forum member 'frenchdrip' (frenchdrip)]
http://forums.java.net/jive/thread.jspa?messageID=276153