JMS-131 (Session is closed) with CachingConnectionFactory and Oracle AQ










0















I'm facing an issue (JMS-131 - Session is closed) regarding the Spring-JMS CachingConnectionFactory in combination with Oracle UCP. Either the CachingConnectionFactory or the JmsTemplate don't seem to react as expected, if the underlying connection of a cached JMS-Session gets closed.



It's actually easy to get an error like this:



org.springframework.jms.IllegalStateException: JMS-131: Session is closed; nested exception is javax.jms.IllegalStateException: JMS-131: Session is closed
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:497)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:668)
at com.example.jms.SessionClosedTest.testJms131(SessionClosedTest.java:171)
...
Caused by: javax.jms.IllegalStateException: JMS-131: Session is closed
at oracle.jms.AQjmsError.throwIllegalStateEx(AQjmsError.java:471)
at oracle.jms.AQjmsSession.checkSessionStarted(AQjmsSession.java:4450)
at oracle.jms.AQjmsSession.getDBConnection(AQjmsSession.java:4392)
at oracle.jms.AQjmsSession.getAQOwner(AQjmsSession.java:6447)
at oracle.jms.AQjmsSession.createQueue(AQjmsSession.java:1387)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386)
at com.sun.proxy.$Proxy73.createQueue(Unknown Source)
at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveQueue(DynamicDestinationResolver.java:84)
at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveDestinationName(DynamicDestinationResolver.java:58)
at org.springframework.jms.support.destination.JmsDestinationAccessor.resolveDestinationName(JmsDestinationAccessor.java:98)
at org.springframework.jms.core.JmsTemplate.access$200(JmsTemplate.java:90)
at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:583)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
... 33 more


Application Configuration



I'm configuring the connection pool like this:



<bean id="appDataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource"
lazy-init="true">
<property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="user" value="$database.username"/>
<property name="password" value="$database.password"/>
<property name="URL" value="$database.url"/>
<property name="initialPoolSize" value="5"/>
<property name="minPoolSize" value="2"/>
<property name="maxPoolSize" value="20"/>
<property name="connectionWaitTimeout" value="10"/>
<property name="inactiveConnectionTimeout" value="180"/>
<property name="timeToLiveConnectionTimeout" value="0"/>
<property name="abandonedConnectionTimeout" value="3"/>
<property name="maxConnectionReuseTime" value="3"/>
<property name="maxConnectionReuseCount" value="0"/>
<property name="validateConnectionOnBorrow" value="true"/>
<property name="maxStatements" value="80"/>
<property name="timeoutCheckInterval" value="3"/>
<property name="connectionProperties">
<props merge="default">
<prop key="oracle.net.disableOob">true</prop>
<prop key="oracle.net.CONNECT_TIMEOUT">10000</prop>
<prop key="oracle.jdbc.ReadTimeout">12000</prop>
</props>
</property>
</bean>


For arguments sake I set the abandonedConnectionTimeout, maxConnectionReuseTime and timeoutCheckInterval to 3, in order to force the ConnectionPool to close all connections that haven't been used for a little while.



XML-Configuration of the CachingConnectionFactory and the JmsTemplate:



<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="sessionCacheSize" value="4"/>
<property name="targetConnectionFactory">
<bean class="com.example.jms.oracleaq.OracleAqConnectionFactoryBean">
<property name="datasource" ref="appDataSource"/>
</bean>
</property>
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="sessionAcknowledgeMode" value="0"/>
<property name="sessionTransacted" value="true"/>
<property name="deliveryPersistent" value="true"/>
<property name="explicitQosEnabled" value="true"/>
<property name="defaultDestinationName" value="SAMPLE_QUEUE"/>
</bean>


Implementation of OracleAqConnectionFactoryBean



public class OracleAqConnectionFactoryBean implements FactoryBean<QueueConnectionFactory> 
...
public QueueConnectionFactory getObject() throws Exception
return oracle.jms.AQjmsFactory.getQueueConnectionFactory(datasource);

...



Test Setup



The test to provoke the JMS-131 error then looks like this:



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/resources/spring/jpa.xml" )
public class SessionClosedTest
@Autowired
private JmsTemplate jmsTemplate;

@Test
public void testRF242() throws Exception
MyBusinessObject someObj = new MyBusinessObject ();
this.jmsTemplate.convertAndSend(someObj);

Thread.sleep(15000);

this.jmsTemplate.convertAndSend(someObj);




The first call of convertAndSend works as expected, however the second call will fail with the Exception at the beginning.



A running application seems to be unable to recover from this error on its own, so that it's necessary to restart that application.



It's possible to get the test above to run successfully if you call CachingConnectionFactory#resetConnection after the sleep.



Questions



The question is, is there anything wrong with the configuration of the JmsTemplate or the CachingConnectionFactory?



For Message-Consumer Spring-JMS is able to handle this situation with the ExceptionListener-Interface. The Framework will call CachingConnectionFactory#resetConnection on its own for Consumer. However for Message-Producer I couldn't find anything similar.



Is Spring-JMS purposely not reacting to JmsExceptions on it's own for Message-Producer? Or is this something that might be missing in Spring?



Used libraries and versions



  • Spring - 4.2.9

  • UCP - 11.1.0.7.0

  • AQ-API - 11.1.0.7.0

  • OJDBC7 - 12.1.0.2

I know they are somewhat old, however in newer versions of Spring I couldn't find anything that helps in my situation.










share|improve this question




























    0















    I'm facing an issue (JMS-131 - Session is closed) regarding the Spring-JMS CachingConnectionFactory in combination with Oracle UCP. Either the CachingConnectionFactory or the JmsTemplate don't seem to react as expected, if the underlying connection of a cached JMS-Session gets closed.



    It's actually easy to get an error like this:



    org.springframework.jms.IllegalStateException: JMS-131: Session is closed; nested exception is javax.jms.IllegalStateException: JMS-131: Session is closed
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:497)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:668)
    at com.example.jms.SessionClosedTest.testJms131(SessionClosedTest.java:171)
    ...
    Caused by: javax.jms.IllegalStateException: JMS-131: Session is closed
    at oracle.jms.AQjmsError.throwIllegalStateEx(AQjmsError.java:471)
    at oracle.jms.AQjmsSession.checkSessionStarted(AQjmsSession.java:4450)
    at oracle.jms.AQjmsSession.getDBConnection(AQjmsSession.java:4392)
    at oracle.jms.AQjmsSession.getAQOwner(AQjmsSession.java:6447)
    at oracle.jms.AQjmsSession.createQueue(AQjmsSession.java:1387)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386)
    at com.sun.proxy.$Proxy73.createQueue(Unknown Source)
    at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveQueue(DynamicDestinationResolver.java:84)
    at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveDestinationName(DynamicDestinationResolver.java:58)
    at org.springframework.jms.support.destination.JmsDestinationAccessor.resolveDestinationName(JmsDestinationAccessor.java:98)
    at org.springframework.jms.core.JmsTemplate.access$200(JmsTemplate.java:90)
    at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:583)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
    ... 33 more


    Application Configuration



    I'm configuring the connection pool like this:



    <bean id="appDataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource"
    lazy-init="true">
    <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
    <property name="user" value="$database.username"/>
    <property name="password" value="$database.password"/>
    <property name="URL" value="$database.url"/>
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="2"/>
    <property name="maxPoolSize" value="20"/>
    <property name="connectionWaitTimeout" value="10"/>
    <property name="inactiveConnectionTimeout" value="180"/>
    <property name="timeToLiveConnectionTimeout" value="0"/>
    <property name="abandonedConnectionTimeout" value="3"/>
    <property name="maxConnectionReuseTime" value="3"/>
    <property name="maxConnectionReuseCount" value="0"/>
    <property name="validateConnectionOnBorrow" value="true"/>
    <property name="maxStatements" value="80"/>
    <property name="timeoutCheckInterval" value="3"/>
    <property name="connectionProperties">
    <props merge="default">
    <prop key="oracle.net.disableOob">true</prop>
    <prop key="oracle.net.CONNECT_TIMEOUT">10000</prop>
    <prop key="oracle.jdbc.ReadTimeout">12000</prop>
    </props>
    </property>
    </bean>


    For arguments sake I set the abandonedConnectionTimeout, maxConnectionReuseTime and timeoutCheckInterval to 3, in order to force the ConnectionPool to close all connections that haven't been used for a little while.



    XML-Configuration of the CachingConnectionFactory and the JmsTemplate:



    <bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="sessionCacheSize" value="4"/>
    <property name="targetConnectionFactory">
    <bean class="com.example.jms.oracleaq.OracleAqConnectionFactoryBean">
    <property name="datasource" ref="appDataSource"/>
    </bean>
    </property>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="sessionAcknowledgeMode" value="0"/>
    <property name="sessionTransacted" value="true"/>
    <property name="deliveryPersistent" value="true"/>
    <property name="explicitQosEnabled" value="true"/>
    <property name="defaultDestinationName" value="SAMPLE_QUEUE"/>
    </bean>


    Implementation of OracleAqConnectionFactoryBean



    public class OracleAqConnectionFactoryBean implements FactoryBean<QueueConnectionFactory> 
    ...
    public QueueConnectionFactory getObject() throws Exception
    return oracle.jms.AQjmsFactory.getQueueConnectionFactory(datasource);

    ...



    Test Setup



    The test to provoke the JMS-131 error then looks like this:



    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(value = "/resources/spring/jpa.xml" )
    public class SessionClosedTest
    @Autowired
    private JmsTemplate jmsTemplate;

    @Test
    public void testRF242() throws Exception
    MyBusinessObject someObj = new MyBusinessObject ();
    this.jmsTemplate.convertAndSend(someObj);

    Thread.sleep(15000);

    this.jmsTemplate.convertAndSend(someObj);




    The first call of convertAndSend works as expected, however the second call will fail with the Exception at the beginning.



    A running application seems to be unable to recover from this error on its own, so that it's necessary to restart that application.



    It's possible to get the test above to run successfully if you call CachingConnectionFactory#resetConnection after the sleep.



    Questions



    The question is, is there anything wrong with the configuration of the JmsTemplate or the CachingConnectionFactory?



    For Message-Consumer Spring-JMS is able to handle this situation with the ExceptionListener-Interface. The Framework will call CachingConnectionFactory#resetConnection on its own for Consumer. However for Message-Producer I couldn't find anything similar.



    Is Spring-JMS purposely not reacting to JmsExceptions on it's own for Message-Producer? Or is this something that might be missing in Spring?



    Used libraries and versions



    • Spring - 4.2.9

    • UCP - 11.1.0.7.0

    • AQ-API - 11.1.0.7.0

    • OJDBC7 - 12.1.0.2

    I know they are somewhat old, however in newer versions of Spring I couldn't find anything that helps in my situation.










    share|improve this question


























      0












      0








      0








      I'm facing an issue (JMS-131 - Session is closed) regarding the Spring-JMS CachingConnectionFactory in combination with Oracle UCP. Either the CachingConnectionFactory or the JmsTemplate don't seem to react as expected, if the underlying connection of a cached JMS-Session gets closed.



      It's actually easy to get an error like this:



      org.springframework.jms.IllegalStateException: JMS-131: Session is closed; nested exception is javax.jms.IllegalStateException: JMS-131: Session is closed
      at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
      at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:497)
      at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
      at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:668)
      at com.example.jms.SessionClosedTest.testJms131(SessionClosedTest.java:171)
      ...
      Caused by: javax.jms.IllegalStateException: JMS-131: Session is closed
      at oracle.jms.AQjmsError.throwIllegalStateEx(AQjmsError.java:471)
      at oracle.jms.AQjmsSession.checkSessionStarted(AQjmsSession.java:4450)
      at oracle.jms.AQjmsSession.getDBConnection(AQjmsSession.java:4392)
      at oracle.jms.AQjmsSession.getAQOwner(AQjmsSession.java:6447)
      at oracle.jms.AQjmsSession.createQueue(AQjmsSession.java:1387)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386)
      at com.sun.proxy.$Proxy73.createQueue(Unknown Source)
      at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveQueue(DynamicDestinationResolver.java:84)
      at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveDestinationName(DynamicDestinationResolver.java:58)
      at org.springframework.jms.support.destination.JmsDestinationAccessor.resolveDestinationName(JmsDestinationAccessor.java:98)
      at org.springframework.jms.core.JmsTemplate.access$200(JmsTemplate.java:90)
      at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:583)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
      ... 33 more


      Application Configuration



      I'm configuring the connection pool like this:



      <bean id="appDataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource"
      lazy-init="true">
      <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
      <property name="user" value="$database.username"/>
      <property name="password" value="$database.password"/>
      <property name="URL" value="$database.url"/>
      <property name="initialPoolSize" value="5"/>
      <property name="minPoolSize" value="2"/>
      <property name="maxPoolSize" value="20"/>
      <property name="connectionWaitTimeout" value="10"/>
      <property name="inactiveConnectionTimeout" value="180"/>
      <property name="timeToLiveConnectionTimeout" value="0"/>
      <property name="abandonedConnectionTimeout" value="3"/>
      <property name="maxConnectionReuseTime" value="3"/>
      <property name="maxConnectionReuseCount" value="0"/>
      <property name="validateConnectionOnBorrow" value="true"/>
      <property name="maxStatements" value="80"/>
      <property name="timeoutCheckInterval" value="3"/>
      <property name="connectionProperties">
      <props merge="default">
      <prop key="oracle.net.disableOob">true</prop>
      <prop key="oracle.net.CONNECT_TIMEOUT">10000</prop>
      <prop key="oracle.jdbc.ReadTimeout">12000</prop>
      </props>
      </property>
      </bean>


      For arguments sake I set the abandonedConnectionTimeout, maxConnectionReuseTime and timeoutCheckInterval to 3, in order to force the ConnectionPool to close all connections that haven't been used for a little while.



      XML-Configuration of the CachingConnectionFactory and the JmsTemplate:



      <bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
      <property name="sessionCacheSize" value="4"/>
      <property name="targetConnectionFactory">
      <bean class="com.example.jms.oracleaq.OracleAqConnectionFactoryBean">
      <property name="datasource" ref="appDataSource"/>
      </bean>
      </property>
      </bean>

      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
      <property name="connectionFactory" ref="jmsConnectionFactory"/>
      <property name="sessionAcknowledgeMode" value="0"/>
      <property name="sessionTransacted" value="true"/>
      <property name="deliveryPersistent" value="true"/>
      <property name="explicitQosEnabled" value="true"/>
      <property name="defaultDestinationName" value="SAMPLE_QUEUE"/>
      </bean>


      Implementation of OracleAqConnectionFactoryBean



      public class OracleAqConnectionFactoryBean implements FactoryBean<QueueConnectionFactory> 
      ...
      public QueueConnectionFactory getObject() throws Exception
      return oracle.jms.AQjmsFactory.getQueueConnectionFactory(datasource);

      ...



      Test Setup



      The test to provoke the JMS-131 error then looks like this:



      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(value = "/resources/spring/jpa.xml" )
      public class SessionClosedTest
      @Autowired
      private JmsTemplate jmsTemplate;

      @Test
      public void testRF242() throws Exception
      MyBusinessObject someObj = new MyBusinessObject ();
      this.jmsTemplate.convertAndSend(someObj);

      Thread.sleep(15000);

      this.jmsTemplate.convertAndSend(someObj);




      The first call of convertAndSend works as expected, however the second call will fail with the Exception at the beginning.



      A running application seems to be unable to recover from this error on its own, so that it's necessary to restart that application.



      It's possible to get the test above to run successfully if you call CachingConnectionFactory#resetConnection after the sleep.



      Questions



      The question is, is there anything wrong with the configuration of the JmsTemplate or the CachingConnectionFactory?



      For Message-Consumer Spring-JMS is able to handle this situation with the ExceptionListener-Interface. The Framework will call CachingConnectionFactory#resetConnection on its own for Consumer. However for Message-Producer I couldn't find anything similar.



      Is Spring-JMS purposely not reacting to JmsExceptions on it's own for Message-Producer? Or is this something that might be missing in Spring?



      Used libraries and versions



      • Spring - 4.2.9

      • UCP - 11.1.0.7.0

      • AQ-API - 11.1.0.7.0

      • OJDBC7 - 12.1.0.2

      I know they are somewhat old, however in newer versions of Spring I couldn't find anything that helps in my situation.










      share|improve this question
















      I'm facing an issue (JMS-131 - Session is closed) regarding the Spring-JMS CachingConnectionFactory in combination with Oracle UCP. Either the CachingConnectionFactory or the JmsTemplate don't seem to react as expected, if the underlying connection of a cached JMS-Session gets closed.



      It's actually easy to get an error like this:



      org.springframework.jms.IllegalStateException: JMS-131: Session is closed; nested exception is javax.jms.IllegalStateException: JMS-131: Session is closed
      at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
      at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:497)
      at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
      at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:668)
      at com.example.jms.SessionClosedTest.testJms131(SessionClosedTest.java:171)
      ...
      Caused by: javax.jms.IllegalStateException: JMS-131: Session is closed
      at oracle.jms.AQjmsError.throwIllegalStateEx(AQjmsError.java:471)
      at oracle.jms.AQjmsSession.checkSessionStarted(AQjmsSession.java:4450)
      at oracle.jms.AQjmsSession.getDBConnection(AQjmsSession.java:4392)
      at oracle.jms.AQjmsSession.getAQOwner(AQjmsSession.java:6447)
      at oracle.jms.AQjmsSession.createQueue(AQjmsSession.java:1387)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:606)
      at org.springframework.jms.connection.CachingConnectionFactory$CachedSessionInvocationHandler.invoke(CachingConnectionFactory.java:386)
      at com.sun.proxy.$Proxy73.createQueue(Unknown Source)
      at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveQueue(DynamicDestinationResolver.java:84)
      at org.springframework.jms.support.destination.DynamicDestinationResolver.resolveDestinationName(DynamicDestinationResolver.java:58)
      at org.springframework.jms.support.destination.JmsDestinationAccessor.resolveDestinationName(JmsDestinationAccessor.java:98)
      at org.springframework.jms.core.JmsTemplate.access$200(JmsTemplate.java:90)
      at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:583)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
      ... 33 more


      Application Configuration



      I'm configuring the connection pool like this:



      <bean id="appDataSource" class="oracle.ucp.jdbc.PoolDataSourceFactory" factory-method="getPoolDataSource"
      lazy-init="true">
      <property name="connectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/>
      <property name="user" value="$database.username"/>
      <property name="password" value="$database.password"/>
      <property name="URL" value="$database.url"/>
      <property name="initialPoolSize" value="5"/>
      <property name="minPoolSize" value="2"/>
      <property name="maxPoolSize" value="20"/>
      <property name="connectionWaitTimeout" value="10"/>
      <property name="inactiveConnectionTimeout" value="180"/>
      <property name="timeToLiveConnectionTimeout" value="0"/>
      <property name="abandonedConnectionTimeout" value="3"/>
      <property name="maxConnectionReuseTime" value="3"/>
      <property name="maxConnectionReuseCount" value="0"/>
      <property name="validateConnectionOnBorrow" value="true"/>
      <property name="maxStatements" value="80"/>
      <property name="timeoutCheckInterval" value="3"/>
      <property name="connectionProperties">
      <props merge="default">
      <prop key="oracle.net.disableOob">true</prop>
      <prop key="oracle.net.CONNECT_TIMEOUT">10000</prop>
      <prop key="oracle.jdbc.ReadTimeout">12000</prop>
      </props>
      </property>
      </bean>


      For arguments sake I set the abandonedConnectionTimeout, maxConnectionReuseTime and timeoutCheckInterval to 3, in order to force the ConnectionPool to close all connections that haven't been used for a little while.



      XML-Configuration of the CachingConnectionFactory and the JmsTemplate:



      <bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
      <property name="sessionCacheSize" value="4"/>
      <property name="targetConnectionFactory">
      <bean class="com.example.jms.oracleaq.OracleAqConnectionFactoryBean">
      <property name="datasource" ref="appDataSource"/>
      </bean>
      </property>
      </bean>

      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
      <property name="connectionFactory" ref="jmsConnectionFactory"/>
      <property name="sessionAcknowledgeMode" value="0"/>
      <property name="sessionTransacted" value="true"/>
      <property name="deliveryPersistent" value="true"/>
      <property name="explicitQosEnabled" value="true"/>
      <property name="defaultDestinationName" value="SAMPLE_QUEUE"/>
      </bean>


      Implementation of OracleAqConnectionFactoryBean



      public class OracleAqConnectionFactoryBean implements FactoryBean<QueueConnectionFactory> 
      ...
      public QueueConnectionFactory getObject() throws Exception
      return oracle.jms.AQjmsFactory.getQueueConnectionFactory(datasource);

      ...



      Test Setup



      The test to provoke the JMS-131 error then looks like this:



      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(value = "/resources/spring/jpa.xml" )
      public class SessionClosedTest
      @Autowired
      private JmsTemplate jmsTemplate;

      @Test
      public void testRF242() throws Exception
      MyBusinessObject someObj = new MyBusinessObject ();
      this.jmsTemplate.convertAndSend(someObj);

      Thread.sleep(15000);

      this.jmsTemplate.convertAndSend(someObj);




      The first call of convertAndSend works as expected, however the second call will fail with the Exception at the beginning.



      A running application seems to be unable to recover from this error on its own, so that it's necessary to restart that application.



      It's possible to get the test above to run successfully if you call CachingConnectionFactory#resetConnection after the sleep.



      Questions



      The question is, is there anything wrong with the configuration of the JmsTemplate or the CachingConnectionFactory?



      For Message-Consumer Spring-JMS is able to handle this situation with the ExceptionListener-Interface. The Framework will call CachingConnectionFactory#resetConnection on its own for Consumer. However for Message-Producer I couldn't find anything similar.



      Is Spring-JMS purposely not reacting to JmsExceptions on it's own for Message-Producer? Or is this something that might be missing in Spring?



      Used libraries and versions



      • Spring - 4.2.9

      • UCP - 11.1.0.7.0

      • AQ-API - 11.1.0.7.0

      • OJDBC7 - 12.1.0.2

      I know they are somewhat old, however in newer versions of Spring I couldn't find anything that helps in my situation.







      java spring jms oracle-aq ucp






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 7:58







      K. Moechel

















      asked Nov 14 '18 at 7:44









      K. MoechelK. Moechel

      12




      12






















          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295247%2fjms-131-session-is-closed-with-cachingconnectionfactory-and-oracle-aq%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53295247%2fjms-131-session-is-closed-with-cachingconnectionfactory-and-oracle-aq%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3