10 Replies Latest reply on May 9, 2011 5:08 PM by iandavies

    JMS Queue Already Exists Exception

    iandavies

      Hi All,

       

      I have an embedded server I am manually creating using JMSServerManagerImpl.  I programmatically set this servers queue configuration object with a single queue.  In addition to the client code using the embedded server in the same process i have a client in another process which is consuming events of this same single queue.

       

      To reproduce this:

       

      If i start the process hosting the embedded server,

      Then start the other client process and wait for it to connect and set up it's message consumer,

      Then kill the server process and

      Finally restart it i get this error:

       

      HornetQException[errorCode=101 message=Queue jms.queue.myQueue already exists]

                at org.hornetq.core.server.impl.HornetQServerImpl.createQueue(HornetQServerImpl.java:1321)

                at org.hornetq.core.server.impl.HornetQServerImpl.createQueue(HornetQServerImpl.java:688)

                at org.hornetq.core.server.impl.ServerSessionImpl.createQueue(ServerSessionImpl.java:354)

                at org.hornetq.core.protocol.core.ServerSessionPacketHandler.handlePacket(ServerSessionPacketHandler.java:251)

                at org.hornetq.core.protocol.core.impl.ChannelImpl.handlePacket(ChannelImpl.java:471)

                at org.hornetq.core.protocol.core.impl.RemotingConnectionImpl.doBufferReceived(RemotingConnectionImpl.java:451)

                at org.hornetq.core.protocol.core.impl.RemotingConnectionImpl.bufferReceived(RemotingConnectionImpl.java:412)

                at org.hornetq.core.remoting.server.impl.RemotingServiceImpl$DelegatingBufferHandler.bufferReceived(RemotingServiceImpl.java:459)

                at org.hornetq.core.remoting.impl.netty.HornetQChannelHandler.messageReceived(HornetQChannelHandler.java:67)

                at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:100)

                at org.jboss.netty.channel.StaticChannelPipeline.sendUpstream(StaticChannelPipeline.java:362)

                at org.jboss.netty.channel.StaticChannelPipeline$StaticChannelHandlerContext.sendUpstream(StaticChannelPipeline.java:514)

                at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:287)

                at org.hornetq.core.remoting.impl.netty.HornetQFrameDecoder2.decode(HornetQFrameDecoder2.java:169)

                at org.hornetq.core.remoting.impl.netty.HornetQFrameDecoder2.messageReceived(HornetQFrameDecoder2.java:134)

                at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80)

                at org.jboss.netty.channel.StaticChannelPipeline.sendUpstream(StaticChannelPipeline.java:362)

                at org.jboss.netty.channel.StaticChannelPipeline.sendUpstream(StaticChannelPipeline.java:357)

                at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)

                at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)

                at org.jboss.netty.channel.socket.oio.OioWorker.run(OioWorker.java:90)

                at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)

                at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)

                at org.jboss.netty.util.VirtualExecutorService$ChildExecutorRunnable.run(VirtualExecutorService.java:181)

                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

                at java.lang.Thread.run(Thread.java:662)

       

      This is happening because my client process, when it sees that the server has come back to life wants to redeploy its JMS queues.  However, my server code has already deployed this queue as part of it's configuration - hence the error.  I've tried using the JMS createQueue method rather than specifying it in the configuration and checking the bindings of the PostOffice of the HornetQServer just before creating it to see if it already exists but this also does not work.

       

      Basically, there seems to be a race condition between my embedded server trying to create the queue and the client process trying to re-create it.

       

      Having looked through the source code there is no equivalent deployQueue for JMS queues (that I can see).  Is there any way i can avoid this error?  As a result the client also complains about a timeout from the server.

       

      Many thanks!

      -ian.

        • 1. JMS Queue Already Exists Exception
          ataylor

          cant you just change your client process to not create the queues?

          • 2. JMS Queue Already Exists Exception
            iandavies

            Hi Andy,

             

            Thanks very much for your reply!  My client process isn't creating any queues.  Rather, it has a message consumer connected to a queue created/configured by the embedded server at startup.  So, what's happening is the client is reconnecting to the server and re-instating the queue itself even though the queue has already been recreated by the configuration at server startup.

             

            Looking through the code at line 945: ClientSessionImpl (2.1.2.Final) you can see what i think is causing the problem.  The comment above this line says: "This allows e.g. JMS non durable subs and temporary queues to continue to be used after failover".  I don't have a failover server configured but somehow i think the same code is being executed for the same server coming back to life.

             

            What the ClientSessionImpl is doing is probably the right thing.  What i would like to do is change this to a deployQueue on JMS rather than a create queue so that, if the configuration has already re-created this queue, this command doesn't fail.

             

            Best regards,

            -ian.

            • 3. JMS Queue Already Exists Exception
              iandavies

              Does anyone have any thoughts on this?  This must surely be a common configuration but i can't see any way of preventing the server from complaining once it is restarted.  Any suggestions would be appreciated.

               

              Best regards,

              -ian.

              • 4. JMS Queue Already Exists Exception
                ataylor

                I'm not sure i fully understand what is happening, are you creating your initial connection after the server has crashed?

                • 5. Re: JMS Queue Already Exists Exception
                  iandavies

                  Hi Andy,

                   

                  Thanks for taking the time to reply.  Here's the steps i take:

                   

                  1) Start the process which embeds the server and programatically setup a non-durable JMS queue (called, say MyQueue).  When i say "programatically", i mean that i manually set up the JMSConfiguration object i pass to the server.

                  2) Start the client process which creates a message consumer for MyQueue.

                  3) Kill the process hosting the embedded server.

                  4) Restart the process hosting the embedded server which programatically sets up the same queue again.

                  5) That server process then logs the error in my first post complaining that MyQueue already exists.

                  6) The client's automatic queue redeployment of MyQueue times out.

                   

                  EDIT: Either 5 or 6 happens!   Usually just 5 since the client wins.

                   

                  I have tried a number of things on the server-side to prevent the queue from being redeployed unless it isn't there but a race condition prevents me from accurately knowing this.  The only "solution" i can come up with is to start the server, wait X seconds for clients to reconnect and then programatically redeploy the queues (checking if they're already there) but this is clearly not a good idea.

                   

                  Take a look at line 945 of ClientSessionImpl (2.1.2.Final) to see where i think the queue is being magically recreated.

                  • 6. Re: JMS Queue Already Exists Exception
                    clebert.suconic

                    you are loading the queue from journal, hence you have to process the exception case the queue already exists.

                     

                    I would just change your client to ignore the exception case it already existed.

                     

                     

                    You can't create a queue again if it already exists.

                     

                     

                    This should be just like ignoring a duplicate exception from the database.

                    • 7. Re: JMS Queue Already Exists Exception
                      iandavies

                      Hi Clebert,

                       

                      Thanks very much for your reply.  Is there any plan to fix this in a future release.  It's not a serious error - just annoying...

                       

                      Best regards,

                      -ian.

                      • 8. Re: JMS Queue Already Exists Exception
                        clebert.suconic

                        There's no bug. We just throw an exception if you create an already existent queue.

                        • 9. Re: JMS Queue Already Exists Exception
                          clebert.suconic

                          You should be able to query it first.

                           

                           

                          It's just like when you add an already existent record on any database, you should get an Exception.

                          • 10. Re: JMS Queue Already Exists Exception
                            iandavies

                            Hi Clebert,

                             

                            I do try to query for it first - i ask the PostOffice if it contains the binding for this queue name but the the PostOffice record is not yet updated.  Just to be clear - the client times out but the server is the one that throws the exception.  As i said this seems to be an unavoidable race condition.

                             

                            I wouldn't say this is a bug, but a nice feature would be to have deployQueue for JMS as you do for HornetQ Core.  With deployQueue, this would not throw any errors.

                             

                            Best regards,

                            -ian.