11 Replies Latest reply on Sep 14, 2007 6:15 AM by stefa975

    JBoss Messaging / Spring JMS compatibility?

    naxius

      Hi,

      Does anyone can give me a feedback about using both JBoss Messaging 1.3.0 and Spring 2.0.6.

      Here is the issue I am facing.

      I am using a JBoss messaging stack with a MDB configured to act as a message controller to route to a valid requested service.
      This is the server part (JBoss 4.2, JDK 1.5 and JBoss Messaging 1.3.0)

      On the client part, I am using Tomcat 6, JDK 1.5 and Spring 2.0.6 (JMS part for that use case).
      On a client request, I am retrieving a JMS sender that is configured within the Spring context. Everything is ok but, after having sent more than 400 messages from the client side, I got several WARN logs and it is not possible anymore to send new JMS messages.

      The following trace is logged in the client part (Spring JMS):

      2007-07-23 17:41:19,731 [Timer-421] WARN org.jboss.remoting.transport.bisocket.BisocketServerInvoker - [] - org.jboss.remoting.transport.bisocket.BisocketServerInvoker$ControlMonitorTimerTask@1bebf37: detected failure on control connection Thread[control: Socket[addr=/10.12.16.19,port=3898,localport=3719],5,main]: requesting new control connection

      and the following trace is logged in the server part (JBoss + JBoss Messaging):

      ERROR [org.jboss.remoting.transport.bisocket.BisocketServerInvoker] Failed to accept socket connection
      java.net.SocketException: Too many open files
      at java.net.PlainSocketImpl.socketAccept(Native Method)
      at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
      at java.net.ServerSocket.implAccept(ServerSocket.java:450)
      at java.net.ServerSocket.accept(ServerSocket.java:421)
      at org.jboss.remoting.transport.bisocket.BisocketServerInvoker$SecondaryServerSocketThread.run(BisocketServerInvoker.java:799)


      I do think that this more a Spring issue due to the fact that Spring is not reusing connection to optimize the number of concurrent TCP/IP connection but, if someone did have the same issue and found a workaround, I would be very please to read it.

      Fyi, I wrote a simple JMS client, with no Spring JMS usage and everything and I do not have this issue.

      Many thanks
      Alexandre

        • 1. Re: JBoss Messaging / Spring JMS compatibility?
          timfox

           

          "aaubry" wrote:


          I do think that this more a Spring issue due to the fact that Spring is not reusing connection to optimize the number of concurrent TCP/IP connection but, if someone did have the same issue and found a workaround, I would be very please to read it.

          Fyi, I wrote a simple JMS client, with no Spring JMS usage and everything and I do not have this issue.


          I remember some time ago other users having problems with Spring and JMS.

          I can't remember the exact details but when we looked at the Spring code we could see it was doing something stupid like opening a new connection, sesssion and producer every time a message was sent (!). I.e. an anti-pattern.

          This scared me at the time, that my advice was to move away from Spring if it's going to do crazy things like that.

          I don't know if they have fixed it since then, but it sounds like they haven't.


          • 2. Re: JBoss Messaging / Spring JMS compatibility?
            nkhadakk

            Hi aaubry,

            I hit a similar issue (with exactly the same versions of Spring/JBoss etc). Did you ever resolve this issue ?

            thank you

            • 3. Re: JBoss Messaging / Spring JMS compatibility?

              Hello nkhadakk,

              I work in the aaubry's team.

              We had not enough time to understand and solve the problem (only 2 days before mount in production env.).

              So, we use now active MQ.



              • 4. Re: JBoss Messaging / Spring JMS compatibility?
                timfox

                If I remember rightly, the problem was due to the Spring JMS template doing some really nasty stuff like opening a connection for each message sent (or consumed - I can't remember).

                So if you're using Spring template with a standard JMS connection factory you're going to get these horrible effects (as well as poor performance).

                A workaround in JBoss should be to make sure you're using the JCA JMS managed connection factory (the thing at java:/JmsXA), rather than a standard connection factory and feed that to Spring.

                The JCA MCF caches connetions internally so it won't actually create a new one each time.

                See http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossJMSRA

                • 5. Re: JBoss Messaging / Spring JMS compatibility?
                  nkhadakk

                  Ok i think i figured it out. Spring has a ton load of configuration options. One of the configurations allows for caching the consumer ... hence reducing the overhead of creating connections etc.

                  <bean id="URIlistener" class="org.springframework.jms.listener.DefaultMessageListenerContainer" lazy-init="false" >
                   <property name="concurrentConsumers" value="${medium.messaging.urimessaging.listener_count}" />
                   <property name="connectionFactory" ref="ConnectionFactory" />
                   <property name="destination" ref="ResolvedURIQueue" />
                   <property name="messageListener" ref="uriEventMessageListener" />
                   <property name="cacheLevel"> <util:constant static-field="org.springframework.jms.listener.DefaultMessageListenerContainer.CACHE_CONSUMER"/>
                   </property>
                   <property name="recoveryInterval" value="100000"/>
                  </bean>
                  
                  <bean id="uriEventMessageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter" lazy-init="false">
                   <property name="delegate">
                   <ref bean="uriEventListener"/>
                   </property>
                   <property name="messageConverter">
                   <null/>
                   </property>
                  </bean>
                  


                  the property 'cacheLevel' being set to 'CACHE_CONSUMER' solves this 'too many open files issue'
                  If not specified the default is 'CACHE_NONE'... and this appears to cause the error





                  • 6. Re: JBoss Messaging / Spring JMS compatibility?
                    stefa975

                    The real problem is that JBM don't pool the connectionFactory. The way Spring is using the connectionFactory is by design and the connectionFactory should be pooled and handled by the application server.

                    • 7. Re: JBoss Messaging / Spring JMS compatibility?
                      clebert.suconic

                      If you want to pool the connectionFactory, use JmsXA. This is a FAQ!

                      This is not a JBM problem!

                      • 8. Re: JBoss Messaging / Spring JMS compatibility?
                        nkhadakk

                        Clebert,

                        If Spring is configured so as not to cache consumers ... it creates new consumer for every receive poll.

                        To avoid this from creating new connections on the Jboss server side should i be using :
                        java:/JMSXA as the connectionFactory ?

                        Even if i do not use transactional messages ?



                        • 9. Re: JBoss Messaging / Spring JMS compatibility?
                          clebert.suconic

                          Caching consumers is certainly not the JMS provider responsability.

                          The same way it's not your database's responsability to cache connections.


                          Using JmsXA will make you cache JMSConnections. If you don't want to do that, you will have to find another way to do it.

                          • 10. Re: JBoss Messaging / Spring JMS compatibility?
                            nkhadakk

                            I guess that answers my question regarding using JmsXA to move connection caching responsibility off the consumer to the provider.
                            thank you.

                            • 11. Re: JBoss Messaging / Spring JMS compatibility?
                              stefa975

                              I added this to jms-ds.xml to get a pool for my Connection

                              <!-- The SIS JMS provider loader -->
                               <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
                               name="jboss.mq:service=JMSProviderLoader,name=SISJMSProvider">
                               <attribute name="ProviderName">DefaultSISJMSProvider</attribute>
                               <attribute name="ProviderAdapterClass">
                               org.jboss.jms.jndi.JNDIProviderAdapter
                               </attribute>
                               <!-- The combined connection factory -->
                               <attribute name="FactoryRef">java:/ClusteredConnectionFactory</attribute>
                               <!-- The queue connection factory -->
                               <attribute name="QueueFactoryRef">java:/ClusteredConnectionFactory</attribute>
                               <!-- The topic factory -->
                               <attribute name="TopicFactoryRef">java:/ClusteredConnectionFactory</attribute>
                               <!-- Uncomment to use HAJNDI to access JMS
                               <attribute name="Properties">
                               java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
                               java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
                               java.naming.provider.url=localhost:1100
                               </attribute>
                               -->
                               </mbean>
                              
                              <tx-connection-factory>
                               <jndi-name>SISJmsXA</jndi-name>
                               <xa-transaction/>
                               <rar-name>jms-ra.rar</rar-name>
                               <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
                               <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property>
                               <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultSISJMSProvider</config-property
                              >
                               <max-pool-size>20</max-pool-size>
                               <!-- <security-domain-and-application>JmsXARealm</security-domain-and-application> -->
                               </tx-connection-factory>
                              


                              Don't forget to remove the security-domain tag. That don't work in JBM. You will only get user: null.