use of javax.ejb.EJBException in project Payara by payara.
the class MessageBeanContainer method beforeMessageDelivery.
/**
* Actual message delivery happens in three steps :
*
* 1) beforeMessageDelivery(Message, MessageListener) This is our chance to
* make the message delivery itself part of the instance's global
* transaction.
*
* 2) onMessage(Message, MessageListener) This is where the container
* delegates to the actual ejb instance's onMessage method.
*
* 3) afterMessageDelivery(Message, MessageListener) Perform transaction
* cleanup and error handling.
*
* We use the EjbInvocation manager's thread-specific state to track the
* invocation across these three calls.
*
* @param method
* @param deliveryType
* @param txImported
* @param resourceHandle
*/
public void beforeMessageDelivery(Method method, MessageDeliveryType deliveryType, boolean txImported, ResourceHandle resourceHandle) {
if (containerState != CONTAINER_STARTED) {
// i.e. no invocation
String errorMsg = localStrings.getLocalString("containers.mdb.invocation_closed", appEJBName_ + ": Message-driven bean invocation closed by container", new Object[] { appEJBName_ });
throw new EJBException(errorMsg);
}
EjbInvocation invocation = createEjbInvocation();
try {
MessageBeanContextImpl context = (MessageBeanContextImpl) getContext(invocation);
if (deliveryType == MessageDeliveryType.Timer) {
invocation.isTimerCallback = true;
}
// Set the context class loader here so that message producer will
// have access to application class loader during message
// processing.
// The previous context class loader will be restored in
// afterMessageDelivery.
invocation.setOriginalContextClassLoader(Utility.setContextClassLoader(getClassLoader()));
invocation.isMessageDriven = true;
invocation.method = method;
context.setState(BeanState.INVOKING);
invocation.context = context;
invocation.instance = context.getEJB();
invocation.ejb = context.getEJB();
invocation.container = this;
// Message Bean Container only starts a new transaction if
// there is no imported transaction and the message listener
// method has tx attribute TX_REQUIRED or the ejbTimeout has
// tx attribute TX_REQUIRES_NEW/TX_REQUIRED
boolean startTx = false;
if (!txImported) {
startTx = containerStartsTx(method);
}
// keep track of whether tx was started for later.
invocation.setContainerStartsTx(startTx);
this.invocationManager.preInvoke(invocation);
if (startTx) {
// Register the session associated with the message-driven
// bean's destination so the message delivery will be
// part of the container-managed transaction.
registerMessageBeanResource(resourceHandle);
}
preInvokeTx(invocation);
} catch (Throwable c) {
if (containerState != CONTAINER_STARTED) {
_logger.log(Level.SEVERE, "containers.mdb.preinvoke_exception", new Object[] { appEJBName_, c.toString() });
_logger.log(Level.SEVERE, c.getClass().getName(), c);
}
invocation.exception = c;
}
}
use of javax.ejb.EJBException in project Payara by payara.
the class MessageBeanContainer method deliverMessage.
public Object deliverMessage(Object[] params) throws Throwable {
EjbInvocation invocation = null;
// for monitoring
boolean methodCalled = false;
Object result = null;
invocation = (EjbInvocation) invocationManager.getCurrentInvocation();
if (invocation == null && _logger.isLoggable(Level.FINEST)) {
if (containerState != CONTAINER_STARTED) {
_logger.log(Level.FINEST, "No invocation in onMessage " + " (container closing)");
} else {
_logger.log(Level.FINEST, "No invocation in onMessage : ");
}
}
if ((invocation != null) && (invocation.exception == null)) {
try {
// NOTE : Application classloader already set in
// beforeMessageDelivery
methodCalled = true;
if (isTimedObject() && isEjbTimeoutMethod(invocation.method)) {
invocation.beanMethod = invocation.method;
intercept(invocation);
} else {
// invocation.beanMethod is the actual target method from
// the bean class. The bean class is not required to be
// a formal subtype of the message listener interface, so
// we need to be careful to invoke through the bean class
// method itself. This info is also returned from the
// interceptor context info.
invocation.methodParams = params;
invocation.beanMethod = invocation.ejb.getClass().getMethod(invocation.method.getName(), invocation.method.getParameterTypes());
result = super.intercept(invocation);
}
} catch (InvocationTargetException ite) {
//
// In EJB 2.1, message listener method signatures do not have
// any restrictions on what kind of exceptions can be thrown.
// This was not the case in J2EE 1.3, since JMS message driven
// beans could only implement
// void javax.jms.MessageListener.onMessage() , which does
// not declare any exceptions.
//
// In the J2EE 1.3 implementation, exceptions were only
// propagated when the message driven bean was not configured
// with CMT/Required transaction mode. This has been changed
// due to the Connector 1.5 integration. Now, all exceptions
// are propagated regardless of the tx mode. (18.2.2)
// Application exceptions are propagated as is, while system
// exceptions are wrapped in an EJBException.
//
// If an exception is thrown and there is a container-started
// transaction, the semantics are the same as for other ejb
// types whose business methods throw an exception.
// Specifically, if the exception thrown is an Application
// exception(defined in 18.2.1), it does not automatically
// result in a rollback of the container-started transaction.
//
Throwable cause = ite.getCause();
// set cause on invocation , rather than the propagated
// EJBException
invocation.exception = cause;
if (isSystemUncheckedException(cause)) {
EJBException ejbEx = new EJBException("message-driven bean method " + invocation.method + " system exception");
ejbEx.initCause(cause);
cause = ejbEx;
}
throw cause;
} catch (Throwable t) {
EJBException ejbEx = new EJBException("message-bean container dispatch error");
ejbEx.initCause(t);
invocation.exception = ejbEx;
throw ejbEx;
} finally {
/*
* FIXME if ( AppVerification.doInstrument() ) {
* AppVerification.getInstrumentLogger().doInstrumentForEjb
* (getEjbDescriptor(), invocation.method,
* invocation.exception); }
*/
}
} else // End if -- invoke instance's onMessage method
{
if (invocation == null) {
String errorMsg = localStrings.getLocalString("containers.mdb.invocation_closed", appEJBName_ + ": Message-driven bean invocation " + "closed by container", new Object[] { appEJBName_ });
throw new EJBException(errorMsg);
} else {
_logger.log(Level.SEVERE, "containers.mdb.invocation_exception", new Object[] { appEJBName_, invocation.exception.toString() });
_logger.log(Level.SEVERE, invocation.exception.getClass().getName(), invocation.exception);
EJBException ejbEx = new EJBException();
ejbEx.initCause(invocation.exception);
throw ejbEx;
}
}
return result;
}
use of javax.ejb.EJBException in project Payara by payara.
the class PersistentEJBTimerService method recoverAndCreateSchedulesError.
/**
* Common code for exception processing in recoverAndCreateSchedules
*/
private void recoverAndCreateSchedulesError(Exception e, TransactionManager tm) {
logger.log(Level.WARNING, "Timer restore or schedule creation error", e);
try {
tm.rollback();
} catch (Exception re) {
logger.log(Level.FINE, "Timer restore or schedule creation rollback error", re);
}
// Propagate the exception caught as an EJBException
EJBException ejbEx = createEJBException(e);
throw ejbEx;
}
use of javax.ejb.EJBException in project Payara by payara.
the class PersistentEJBTimerService method migrateTimers.
/**
* Take ownership of another server's timers.
*/
public int migrateTimers(String fromOwnerId) {
String ownerIdOfThisServer = getOwnerIdOfThisServer();
if (fromOwnerId.equals(ownerIdOfThisServer)) {
// / Error. The server from which timers are being
// migrated should never be up and running OR receive this
// notification.
logger.log(Level.WARNING, "Attempt to migrate timers from " + "an active server instance " + ownerIdOfThisServer);
throw new IllegalStateException("Attempt to migrate timers from " + " an active server instance " + ownerIdOfThisServer);
}
logger.log(Level.INFO, "Beginning timer migration process from " + "owner " + fromOwnerId + " to " + ownerIdOfThisServer);
TransactionManager tm = ejbContainerUtil.getTransactionManager();
Set toRestore = null;
int totalTimersMigrated = 0;
try {
tm.begin();
toRestore = timerLocal_.findTimersOwnedBy(fromOwnerId);
totalTimersMigrated = timerLocal_.migrateTimers(fromOwnerId, ownerIdOfThisServer);
tm.commit();
} catch (Exception e) {
// Don't attempt to restore any timers since an error has
// occurred. This could be the expected result in the case that
// multiple server instances attempted the migration at the same
// time.
logger.log(Level.FINE, "timer migration error", e);
try {
tm.rollback();
} catch (Exception re) {
logger.log(Level.FINE, "timer migration rollback error", re);
}
// Propagate the exception caught
EJBException ejbEx = createEJBException(e);
throw ejbEx;
}
// XXX if( totalTimersMigrated == toRestore.size() ) { XXX ???
if (totalTimersMigrated > 0) {
boolean success = false;
try {
logger.log(Level.INFO, "Timer migration phase 1 complete. " + "Changed ownership of " + toRestore.size() + " timers. Now reactivating timers...");
_notifyContainers(toRestore);
tm.begin();
_restoreTimers(toRestore);
success = true;
} catch (Exception e) {
logger.log(Level.FINE, "timer restoration error", e);
// Propogate any exceptions caught as part of the transaction
EJBException ejbEx = createEJBException(e);
throw ejbEx;
} finally {
// always committing.
try {
tm.commit();
} catch (Exception re) {
logger.log(Level.FINE, "timer migration error", re);
if (success) {
// Propogate any exceptions caught when trying to commit
// the transaction
EJBException ejbEx = createEJBException(re);
throw ejbEx;
}
}
}
} else {
logger.log(Level.INFO, fromOwnerId + " has 0 timers in need " + "of migration");
}
return totalTimersMigrated;
}
use of javax.ejb.EJBException in project quickstart by wildfly.
the class CustomerManagerEJB method createCustomer.
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void createCustomer(String name) throws RemoteException, JMSException {
logMessageManager.logCreateCustomer(name);
Customer c1 = new Customer();
c1.setName(name);
entityManager.persist(c1);
invoiceManager.createInvoice(name);
// after the fact but before the transaction is committed.
if (!nameIsValid(name)) {
throw new EJBException("Invalid name: customer names should only contain letters & '-'");
}
}
Aggregations