1

I'm finding some difficulties in trying to reduce the connection and session creation when sending messages to a Jboss Queue.

<bean name="jbmTemplate-${jbmQueue}" class="org.springframework.jms.core.JmsTemplate" lazy-init="true">
        <property name="sessionTransacted" value="true" />

    <!-- connection factory -->
    <property name="connectionFactory">
        <ref bean="jbmCachingConnectionFactory"/>
    </property>

    <property name="pubSubDomain">
        <value>false</value>
    </property>

    <property name="receiveTimeout">
        <value>${jmsReceiveTimeout}</value>
    </property>

</bean>

I'm using a JmsTemplate to send messages:

<bean id="jbmCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
     <property name="targetConnectionFactory" ref="jbmConnectionFactory" />
</bean>

And the jbmConnectionFactory is defined as follow:

<jee:jndi-lookup id="jbmConnectionFactory" jndi-name="XAConnectionFactory"
        resource-ref="true" lookup-on-startup="false" proxy-interface="javax.jms.ConnectionFactory"
        cache="false">
    <jee:environment>
        java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
        java.naming.provider.url=${jbmURL}
        java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
    </jee:environment>
</jee:jndi-lookup>

I'm using this piece of code to send messages to Jboss:

public void send(final Serializable payload, final String correlationId) {
    log.debug("payload: {}", payload);

    try {
        jmsQueueTemplate.send(destinationName, new MessageCreator() {
            public Message createMessage(Session session)
                    throws JMSException {
                ObjectMessage msg = session.createObjectMessage(payload);

                msg.setJMSType(payload.getClass().getCanonicalName());
                msg.setJMSCorrelationID(correlationId);

                return msg;
            }

        });
    } catch (Exception e) {
        log.error("Couldn't send message");
        throw new BlockingException(e);
    }
}

What I was trying to do by using the CachingConnectionFactory is to avoid creating and closing connections and sessions every message I send but as far as I can see, when using a JmsTemplate, no matter what type of connectionFactory I use, the connection and session will always be terminated:

finally {
            JmsUtils.closeSession(sessionToClose);
            ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
        }

Am I calling the wrong method? Is there something that I don't get?

Massimo
  • 692
  • 2
  • 11
  • 29

1 Answers1

2

The CachingConnectionFactory returns a proxy (wrapper) for the connection which ignores the close(). Similarly, session.close() is intercepted and the session is put in the cache instead of actually closing it.

In fact, it requires the session to be "closed" so the session can be made available for the next use.

You may need to configure the cache size (it's only 1 by default; see the javadocs).

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Hi @Gary, I've configured the cache size and increased it to 10 but the issue persists. What I'm seeing is that when we are inside the "doGetTransactionalSession" method inside the execute: `Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession( getConnectionFactory(), this.transactionalResourceFactory, startConnection);` When he creates a new ` resourceHolderToUse = new JmsResourceHolder(connectionFactory); ` He creates a JmsResourceHolder with no connection inside of it, hence he proceeds at creating it again. – Massimo Mar 06 '15 at 14:33
  • Right, but since the `CachingConnectionFactory` only has one connection (it is a subclass of `SingleConnectionFactory`) he gets the same connection. – Gary Russell Mar 06 '15 at 15:00
  • That's strange because I'm enqueuing messages and at the same time monitoring the connections on the receiving's machine and I'm seeing that everytime I enqueue a message the number of connections goes up (and comes back down after a while). Is it working as intended? Thanks – Massimo Mar 06 '15 at 15:05
  • No; there must be something wrong with your configuration - there is only ever one connection from the CCF. You will get lots of information if you enable TRACE logging. – Gary Russell Mar 06 '15 at 15:57
  • @Gary what would be the best approach in case the connection factory was managed by JCA in the container. I have a somehow similar concern with caching. Wouldn't the caching mechanism of JCA be redundant? I posted question(http://stackoverflow.com/questions/28844426/springs-defaultmessagelistenercontainer-to-use-connection-factory-directly-from where I would appreciate your perspective. Thanks – Camilo Crespo Mar 06 '15 at 17:33
  • It probably varies by provider; I don't have any specific general advice (otherwise I would have answered that question). – Gary Russell Mar 06 '15 at 19:25
  • Oh, as always, you are right. Here is the proof: The first two are the connections (first being the one cached in the conn. factory, the second being the conn. being "created") Shared JMS Connection: JBossConnection->ConnectionDelegate[5378289, ID=msa-rucdvy6i-1-i0l4ox6i-xs7g6u-111606a, SID=90] Shared JMS Connection: JBossConnection->ConnectionDelegate[5378289, ID=msa-rucdvy6i-1-i0l4ox6i-xs7g6u-111606a, SID=90] The same happens for the sessions. Thanks again! :) Then I guess maybe there's something on Jboss's side not closing the connections? – Massimo Mar 07 '15 at 10:37