JMS-131 (Session is closed) with CachingConnectionFactory and Oracle AQ
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
add a comment |
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
add a comment |
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
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
java spring jms oracle-aq ucp
edited Nov 14 '18 at 7:58
K. Moechel
asked Nov 14 '18 at 7:44
K. MoechelK. Moechel
12
12
add a comment |
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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