3 Replies Latest reply on Oct 26, 2004 10:53 AM by Wolf-Dieter Fink

    Cannot read from DLQ with JDBC persistence

    guyug Newbie

      Hi,

      I have configured jboss 3.2.1 to use JDBC2 PersistenceManager with MySQL. I want to read messages from DLQ.
      The problem is that even though there are messages in the DLQ (I also see them in the JMS_MESSAGES table), when I try to receive them I get that the queue is empty. Does anyone know what the problem might be?

      Thanks,
      Guy.

      The (relevant) jbossmq-service.xml configuration:

      <server>
      ===================== -->
       <!-- Invocation Layers -->
       <!-- ==================================================================== -->
       <mbean code="org.jboss.mq.il.jvm.JVMServerILService"
       name="jboss.mq:service=InvocationLayer,type=JVM">
       <depends optional-attribute-name="Invoker">jboss.mq:service=Invoker</depends>
       <attribute name="ConnectionFactoryJNDIRef">java:/ConnectionFactory</attribute>
       <attribute name="XAConnectionFactoryJNDIRef">java:/XAConnectionFactory</attribute>
       <attribute name="PingPeriod">0</attribute>
       </mbean>
      
       <!-- ==================================================================== -->
       <!-- JBossMQ Interceptor chain configuration -->
       <!-- ==================================================================== -->
       <!-- and/or the SecurityManager, but then you loose the ability to trace and/or enforce security. -->
       <mbean code="org.jboss.mq.server.jmx.Invoker" name="jboss.mq:service=Invoker">
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=TracingInterceptor</depends>
       </mbean>
      
       <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=TracingInterceptor">
       <attribute name="InterceptorClass">org.jboss.mq.server.TracingInterceptor</attribute>
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager</depends>
       </mbean>
      
       <mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=SecurityManager">
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends>
       </mbean>
      
       <!--
       | The ClientMonitorInterceptor disconnects clients that have been idle for to long.
       | This interceptor is not enabled by default since the server might disconnect clients
       | when the it is under high load.
       -->
       <!--
       <mbean code="org.jboss.mq.server.jmx.ClientMonitorInterceptor" name="jboss.mq:service=ClientMonitorInterceptor">
       <attribute name="ClientTimeout">80000</attribute>
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=ClientReconnectInterceptor</depends>
       </mbean>
       -->
      
       <!--
       <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=ClientReconnectInterceptor">
       <attribute name="InterceptorClass">org.jboss.mq.server.ClientReconnectInterceptor</attribute>
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends>
       </mbean>
       -->
      
       <mbean code="org.jboss.mq.server.jmx.DestinationManager" name="jboss.mq:service=DestinationManager">
       <depends optional-attribute-name="PersistenceManager">jboss.mq:service=PersistenceManager</depends>
       <depends optional-attribute-name="StateManager">jboss.mq:service=StateManager</depends>
       </mbean>
      
       <!--
       | The MessageCache decides where to put JBossMQ message that
       | are sitting around waiting to be consumed by a client.
       |
       | The memory marks are in Megabytes. Once the JVM memory usage hits
       | the high memory mark, the old messages in the cache will start getting
       | stored in the DataDirectory. As memory usage gets closer to the
       | Max memory mark, the amount of message kept in the memory cache aproaches 0.
       |
       | ATTENTION: When the "file" or "rollinglogged" Persistence Manager is used
       | you have to set the "CacheStore" to the CacheStore (the commented out line)
       | and not to the PM itself.
       -->
       <mbean code="org.jboss.mq.server.MessageCache"
       name="jboss.mq:service=MessageCache">
       <attribute name="HighMemoryMark">900</attribute>
       <attribute name="MaxMemoryMark">1000</attribute>
       <attribute name="CacheStore">jboss.mq:service=PersistenceManager</attribute>
       </mbean>
      
       <!--
       | The CacheStore decides where to store JBossMQ message that
       | that the MessageCache has decided to move in secondary storage.
       |
       | Now you can specify a absolut path by using an ULR like:
       | file:///c:/temp
       | ATTENTION: the directory MUST exists because it will not be
       | created.
       <mbean code="org.jboss.mq.pm.file.CacheStore"
       name="jboss.mq:service=CacheStore">
       <attribute name="DataDirectory">tmp/jbossmq</attribute>
       </mbean>
       -->
      
       <!--
       | The StateManager is used to keep JMS persistent state data.
       | For example: what durable subscriptions are active.
       -->
       <mbean code="org.jboss.mq.sm.file.DynamicStateManager"
       name="jboss.mq:service=StateManager">
       <!-- This file is pulled from the configuration URL of the server -->
       <attribute name="StateFile">jbossmq-state.xml</attribute>
       </mbean>
      
       <!--
       | The PersistenceManager is used to store messages to disk.
       |
       | Now you can specify a absolut path by using an ULR like:
       | file:///c:/temp
       | ATTENTION: the directory MUST exists because it will not be
       | created. Also for the "file" Persistance Manager the directory
       | MUST be empty otherwise the startup fails ("rollinglogged" works
       | fine.
       <mbean code="org.jboss.mq.pm.file.PersistenceManager"
       name="jboss.mq:service=PersistenceManager">
       <attribute name="DataDirectory">data/jbossmq/file</attribute>
       <depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache</depends>
       </mbean>
       -->
      
      
       <!--
       | The jdbc2 PersistenceManager is the new improved JDBC implementation.
       | This implementation allows you to control how messages are stored in
       | the database.
       |
       | Use this PM if you want the reliablity a relational database can offer
       | you. The default configuration is known to work with hsqldb, other databases
       | will requrie teaking of the SqlProperties.
       -->
       <mbean code="org.jboss.mq.pm.jdbc2.PersistenceManager"
       name="jboss.mq:service=PersistenceManager">
       <depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache</depends>
       <depends optional-attribute-name="ConnectionManager">jboss.jca:service=LocalTxCM,name=DefaultDS</depends>
       <attribute name="SqlProperties">
       BLOB_TYPE=BYTES_BLOB
       INSERT_TX = INSERT INTO JMS_TRANSACTIONS (TXID) values(?)
       INSERT_MESSAGE = INSERT INTO JMS_MESSAGES (MESSAGEID, DESTINATION, MESSAGEBLOB, TXID, TXOP) VALUES(?,?,?,?,?)
       SELECT_ALL_UNCOMMITED_TXS = SELECT TXID FROM JMS_TRANSACTIONS
       SELECT_MAX_TX = SELECT MAX(TXID) FROM JMS_MESSAGES
       SELECT_MESSAGES_IN_DEST = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE DESTINATION=?
       SELECT_MESSAGE = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
       MARK_MESSAGE = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE MESSAGEID=? AND DESTINATION=?
       UPDATE_MESSAGE = UPDATE JMS_MESSAGES SET MESSAGEBLOB=? WHERE MESSAGEID=? AND DESTINATION=?
       UPDATE_MARKED_MESSAGES = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=?
       UPDATE_MARKED_MESSAGES_WITH_TX = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=? AND TXID=?
       UPDATE_MESSAGE = UPDATE JMS_MESSAGES SET MESSAGEBLOB=? WHERE MESSAGEID=? AND DESTINATION=?
       UPDATE_MARKED_MESSAGES = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=?
       UPDATE_MARKED_MESSAGES_WITH_TX = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=? AND TXID=?
       DELETE_MARKED_MESSAGES_WITH_TX = DELETE JMS_MESSAGES FROM JMS_MESSAGES, JMS_TRANSACTIONS WHERE JMS_MESSAGES.TXID = JMS_TRANSACTIONS.TXID AND JMS_MESSAGES.TXOP=?
       DELETE_TX = DELETE FROM JMS_TRANSACTIONS WHERE TXID = ?
       DELETE_MARKED_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXID=? AND TXOP=?
       DELETE_TEMPORARY_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXOP='T'
       DELETE_MESSAGE = DELETE FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
       CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES (MESSAGEID INTEGER NOT NULL, DESTINATION VARCHAR(150) NOT NULL, TXID INTEGER, TXOP CHAR(1), MESSAGEBLOB BLOB, PRIMARY KEY (MESSAGEID, DESTINATION))
       CREATE_TX_TABLE = CREATE TABLE JMS_TRANSACTIONS (TXID INTEGER)
       CREATE_TABLES_ON_STARTUP = TRUE
       </attribute>
       </mbean>
      
       <!-- ==================================================================== -->
       <!-- System Destinations -->
       <!-- ==================================================================== -->
      
       <!-- Dead Letter Queue -->
       <mbean code="org.jboss.mq.server.jmx.Queue"
       name="jboss.mq.destination:service=Queue,name=DLQ">
       <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
       <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
       <attribute name="JNDIName">queue/DLQ</attribute>
       </mbean>
      


        • 1. Re: Cannot read from DLQ with JDBC persistence
          Wolf-Dieter Fink Master

          hi,
          I use a Client with the QueueBrowse function to read the DLQ.
          And I have no Problems, her a pice of my code (from a swing client):

           try {
           QueueConnection qc=de.intermoves.pbseasyzds.admin.Session.getJMSQueueConnection();
           Queue jmsq=de.intermoves.pbseasyzds.admin.Session.getJMSQueue(queueName);
           QueueSession session = qc.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
          
           DefaultListModel model=new DefaultListModel();
           for(Enumeration e=session.createBrowser(jmsq).getEnumeration();e.hasMoreElements();){
           Message msg=(Message)e.nextElement();
           model.addElement(msg);
           }
           this.queueEntries.setModel(model);
          
           session.close();
           qc.close();
           }catch(JMSException e) {
           log4j.error("Fehler JMS",e);
           }catch(NamingException e) {
           log4j.error("Fehler JNDI",e);
           }
          


          in which way you read the DLQ entries?

          Wolf

          • 2. Re: Cannot read from DLQ with JDBC persistence
            guyug Newbie

            I used receiveNoWait().
            When I tried QueueBrowser it worked! Thanks!

            Since receiveNoWait() doesnt work for me, do you know how I can delete a message from the DLQ?

            • 3. Re: Cannot read from DLQ with JDBC persistence
              Wolf-Dieter Fink Master

              Hi guyug,
              here is my code that works fine in my client....

               private void deleteQueueEntry(String jmsMessageID) throws JMSException,NamingException {
               QueueConnection qc=de.intermoves.pbseasyzds.admin.Session.getJMSQueueConnection();
               Queue jmsq=de.intermoves.pbseasyzds.admin.Session.getJMSQueue((String)this.queue.getSelectedKey());
               QueueSession session = qc.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
               QueueReceiver recv = session.createReceiver(jmsq,"JMSMessageID='"+jmsMessageID+"'");
               session.setMessageListener(new MessageListener() {
               public void onMessage(Message msg) {
               if(log4j.isDebugEnabled()) log4j.debug("Loesche JMS Message "+msg);
               }
               });
               qc.start();
               recv.receive(1000); // Message aus der Queue lesen wenn noch vorhanden
               qc.stop();
               session.close();
               qc.close();
               }