My basic problem:
the MessageDriven
bean throws an Exception
somewhere, which leads to a rollback in the JMS Queue
until it just blows up and the server breaks down. I can't even look for the Exceptions
to solve the problem because the server-logs grow to a few hundred MB in only a few Minutes.
What I am looking for:
a way to first clear the JMS Queue
and then stop the rollbacks once and for all.
This is what I do:
the object stateless bean to Message-Driven Bean here it throws I want to send send the ObjectMessage to receive the message the Exception +-----------+ +-----------------+ +-----------------+ +----------+ | MyObject |----->| MessageProducer |------->| MessageReceiver |---->| do stuff | +-----------+ +-----------------+ +-----------------+ +----------+
The object I send is a simple serializable
POJO.
The MessageProducer looks like this:
@Stateless
public class MessageProducer{
@Resource(mappedName = "jms/JMSConnectionFactory")
private ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/MessageReceiver")
Queue messageReceiver;
public void sendMessage(PostContainer postContainer){
MessageProducer messageProducer;
// try with resources to close everything on Exception
try(Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)){
messageProducer = session.createProducer(messageReceiver);
ObjectMessage objectMessage = session.createObjectMessage();
objectMessage.setObject(myObject);
objectMessage.setJMSRedelivered(false); // this doesn't seem to have any effect
messageProducer.send(objectMessage);
messageProducer.close();
}catch(Exception ex){
System.out.err("error when sendingMessage .. ignoring"); // when "ignoring" the Exception I thought to at least save me the enormous log messages
}
}
}
The message bean looks like this:
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/MessageReceiver")
})
public class MessageReceiver implements MessageListener{
public MessageReceiver(){
}
@Override
public void onMessage(Message message){
try{
if(message instanceof ObjectMessage){
ObjectMessage objectMessage = (ObjectMessage) message;
MyObject myObject = (MyObject) objectMessage.getObject();
doStuff(myObject); // the method that handles the incoming object - here the Exception gets thrown
}
}catch(Exception ex){
System.err.println("message could not be received: " + ex.getMessage()); // still trying to ignore exceptions here
}
}
}
Some part of the Exception
javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
at com.sun.ejb.containers.EJBContainerTransactionManager.checkExceptionClientTx(EJBContainerTransactionManager.java:662)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
......... (and so on....)
at com.me.MessageBeans.MessageReceiver.doStuff(MessageReceiver.java:86)
at com.me.MessageBeans.MessageReceiver.onMessage(MessageReceiver.java:61)
at sun.reflect.GeneratedMethodAccessor313.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor310.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
......... (and so on....)
Caused by: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.
// I try to persist myObject with JPA into the database (that's what's not working right now.. but it's beside the point here
......... (and so on....)
Now my actual question
:)How can I stop my
JMS Queue
to redeliver messages (that cause any Exceptions
or could not be delivered successfully for any other reason) ? (e.g catching the exceptions, setting some parameters when sending the message...)
Is there a parameter/option I have to set in GlassFish when setting up the DestinationResources or ConnectionFactories ?
And how could I clear the Queue manually, because right now it's full with "redeliver messages" and every time I deploy my application I get flooded with log messages within minutes.
Thank you all for your time and for reading :)