2012-08-01 2 views
3

Ma demande est en cours d'exécution sur Jboss 7.1.1. J'ai un planificateur qui s'exécute toutes les minutes et doit vérifier s'il y a des messages dans le DLQ et faire quelques mises à jour dans la base de données.MessageConsumer ne consomme pas les messages

J'ai écrit un consommateur de message qui écoute un DLQ personnalisé prédéfini. Le problème est que je peux voir qu'il y a des messages dans le DLQ personnalisé, mais consumer.receiveNoWait() retourne toujours null.

Voici le code pour créer le consommateur:

/*this is running fine and creating the consumer*/ 
public DestinationHandlerImpl(ConnectionFactory connectionFactory, 
    Destination destination, boolean useTransaction, int delMode, 
    boolean isProducer) throws JMSException { 
    connection = connectionFactory.createConnection(); 
    consumer = session.createConsumer(destination); 
} 

Voici le code qui consomme le message (exécute toutes les minutes):

/*this always return null, event when there are messages in the queue*/ 
public <T extends BaseEvent> T recieveMessage() 
     throws JMSException { 

    Message message = consumer.receiveNoWait(); // ----> always return null!!! 

    if (message != null && !(message instanceof ObjectMessage)) { 
     throw new IllegalArgumentException(
       "message object has to be of type ObjectMessage"); 
    } 

    // Extract the object from the message 
    return message == null ? null : (T) ((ObjectMessage) message).getObject(); 

} 

Je l'ai utilisé le mode de débogage et i peut voir la propriété de destination du consommateur est mis à la bonne file d'attente, alors qu'est-ce que je fais mal?

Répondre

9

Je l'ai trouvé, je voulais juste ajouter connection.start() avant de commencer à consommer.

public <T extends BaseEvent> T recieveMessage() 
    throws JMSException { 

    connection.start(); // --->**added this line** 
    Message message = consumer.receiveNoWait(); 

    if (message != null && !(message instanceof ObjectMessage)) { 
     throw new IllegalArgumentException(
      "message object has to be of type ObjectMessage"); 
    } 

    // Extract the object from the message 
    return message == null ? null : (T) ((ObjectMessage) message).getObject(); 
} 
+0

Je pense que vous ne voulez pas continuer à appeler '' chaque minute start(), mais vous devez appeler qu'une fois lorsque vous ouvrez la connexion. – seh

+0

Je m'assure de fermer la connexion chaque fois que le planificateur démarre. – Tomer

+0

Puis-je demander pourquoi? Êtes-vous concerné par la consommation de ressources de la connexion ouverte? – seh

0

J'ai eu ce problème même avec connection.start()! La solution de travail pour moi:

Utilisez receive(long timeout) au lieu de receiveNoWait();

Obs 1000 millisecondes que le délai d'attente a bien fonctionné dans un cas de test simple, mais juste pour être sûr à la production, je la configuration avec 10000 millisecondes. Dans mon cas, les messages tout en réitérant, je me arrête quand je reçois null (pas plus de messages) et en ce dernier appel, la réception (10000) attend la totalité des 10 secondes (évidemment). J'ai dû utiliser une approche asynchrone pour atténuer ce problème de performance.


Edit: également, en fonction de la mise en œuvre (JBM), il peut avoir des messages prélecture (présélectionné à consommer) et qui rend les messages disponibles étant donné qu'ils sont à fournir statut.

+1

Je semble avoir le même problème. Je n'aime vraiment pas appeler recevoir avec timeout, parce que c'est (par définition) une condition de course. Vous en apprenez toujours plus à ce sujet? – fool4jesus

+0

@ fool4jesus Désolé, je n'ai rien trouvé d'autre dans mes recherches sur ce cas. En fait, ce qui précède a vraiment bien fonctionné pour moi. – falsarella

Questions connexes