Synchronous Consumer with JMS Queue

…衆ロ難τιáo~ 提交于 2020-01-06 07:03:16

问题


I want to process all the messages from a JMS Queue in Glassfish 3 in a synchronous way so I have tried to change the property Maximum Active Consumers from -1 to 1 in JMS Physical Destination in Glassfish window. I think setting this I will have only one Consumer executing OnMessage() at the same time. The problem I have reached its that when I change that property I got this error:

[I500]: Caught JVM Exception: org.xml.sax.SAXParseException: Content is not allowed in prolog.

[I500]: Caught JVM Exception: com.sun.messaging.jms.JMSException: Content is not allowed in prolog.

sendMessage Error [C4038]: com.sun.messaging.jms.JMSException: Content is not allowed in prolog.

If anyone know another way to make the method onmessage() synchronous will be appreciated. This is my Consumer Class:

@MessageDriven(mappedName = "QueueListener", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class MessageBean implements MessageListener {



@Override
public void onMessage(Message message) {
    long t1 = System.currentTimeMillis();
    write("MessageBean has received " + message);
    try{

        TextMessage result=(TextMessage)message;
        String text=result.getText();
        write("OTAMessageBean message ID has resolved to " + text);
        int messageID=Integer.valueOf(text);

        AirProcessing aP=new AirProcessing();
        aP.pickup(messageID);


    }
    catch(Exception e){
        raiseError("OTAMessageBean error " + e.getMessage());
    }
   long t2 = System.currentTimeMillis();
   write("MessageBean has finished in " + (t2-t1)); 

}



}

回答1:


I had the same problem, the only solution I found was to set up a Schedule which polls the messages from the queue every ten seconds:

@Stateless
public class MyReceiver {
   @Resource(mappedName = "jms/MyQueueFactory")
   private QueueConnectionFactory connectionFactory;
   @Resource(mappedName = "jms/MyQueue")
   private Queue myQueue;
   private QueueConnection qc;
   private QueueSession session;
   private MessageConsumer consumer;


   @PostConstruct
   void init() {
       try {
         qc = connectionFactory.createQueueConnection();
         session = qc.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
         consumer = session.createConsumer(myQueue);
         qc.start();
       } catch (JMSException e) {
         throw new RuntimeException(e);
       }
   }

   @PreDestroy
   void cleanup() throws JMSException {
     qc.close();
   }

   @Schedule(hour = "*", minute = "*", second = "*/10", persistent = false)
   public void onMessage() throws JMSException {
     Message message;
     while ((message = consumer.receiveNoWait()) != null) {
       ObjectMessage objMsg = (ObjectMessage) message;
       Serializable content;
       try {
         content = objMsg.getObject();

         //Do sth. with "content" here

         message.acknowledge();
       } catch (JMSException ex) {
         ex.printStackTrace();
       }
    }
  }
}



回答2:


JMS is async by nature, you don't have a specific config for telling io to behave synchronously. You can simulate it by adding message delivery and consumption confirmations everywhere, but that's not really how JMS is intended to work. Try RMIenter link description here or maybe HTTP (or something on top of it like a SOAP or REST web service)



来源:https://stackoverflow.com/questions/12528818/synchronous-consumer-with-jms-queue

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!