Reputation: 1325
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));
}
}
Upvotes: 0
Views: 2405
Reputation: 2071
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();
}
}
}
}
Upvotes: 3
Reputation: 15219
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)
Upvotes: 1