use of org.apache.openejb.InvalidateReferenceException in project tomee by apache.
the class EjbHomeProxyHandler method _invoke.
@Override
protected Object _invoke(final Object proxy, final Class interfce, final Method method, final Object[] args) throws Throwable {
final String methodName = method.getName();
if (logger.isDebugEnabled()) {
logger.debug("EjbHomeProxyHandler: invoking method " + methodName + " on " + deploymentID);
}
try {
final Object retValue;
final MethodType operation = dispatchTable.get(methodName);
if (operation == null) {
retValue = homeMethod(interfce, method, args, proxy);
} else {
switch(operation) {
/*-- CREATE ------------- <HomeInterface>.create(<x>) ---*/
case CREATE:
retValue = create(interfce, method, args, proxy);
break;
case FIND:
retValue = findX(interfce, method, args, proxy);
break;
/*-- GET EJB METADATA ------ EJBHome.getEJBMetaData() ---*/
case META_DATA:
retValue = getEJBMetaData(method, args, proxy);
break;
/*-- GET HOME HANDLE -------- EJBHome.getHomeHandle() ---*/
case HOME_HANDLE:
retValue = getHomeHandle(method, args, proxy);
break;
/*-- REMOVE ------------------------ EJBHome.remove() ---*/
case REMOVE:
{
final Class type = method.getParameterTypes()[0];
/*-- HANDLE ------- EJBHome.remove(Handle handle) ---*/
if (Handle.class.isAssignableFrom(type)) {
retValue = removeWithHandle(interfce, method, args, proxy);
} else {
/*-- PRIMARY KEY ----- EJBHome.remove(Object key) ---*/
retValue = removeByPrimaryKey(interfce, method, args, proxy);
}
break;
}
default:
throw new OpenEJBRuntimeException("Inconsistent internal state: value " + operation + " for operation " + methodName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("EjbHomeProxyHandler: finished invoking method " + method.getName() + ". Return value:" + retValue);
}
return retValue;
/*
* The ire is thrown by the container system and propagated by
* the server to the stub.
*/
} catch (final RemoteException re) {
if (interfaceType.isLocal()) {
throw new EJBException(re.getMessage()).initCause(re.detail);
} else {
throw re;
}
} catch (final InvalidateReferenceException ire) {
Throwable cause = ire.getRootCause();
if (cause instanceof RemoteException && interfaceType.isLocal()) {
final RemoteException re = (RemoteException) cause;
final Throwable detail = re.detail != null ? re.detail : re;
cause = new EJBException(re.getMessage()).initCause(detail);
}
throw cause;
/*
* Application exceptions must be reported dirctly to the client. They
* do not impact the viability of the proxy.
*/
} catch (final ApplicationException ae) {
final Throwable exc = ae.getRootCause() != null ? ae.getRootCause() : ae;
if (exc instanceof EJBAccessException) {
if (interfaceType.isBusiness()) {
throw exc;
} else {
if (interfaceType.isLocal()) {
throw (AccessLocalException) new AccessLocalException(exc.getMessage()).initCause(exc);
} else {
try {
throw new AccessException(exc.getMessage()).initCause(exc);
} catch (final IllegalStateException vmbug) {
// bug affects using initCause on any RemoteException subclasses in Sun 1.5_07 or lower
throw new AccessException(exc.getMessage(), (Exception) exc);
}
}
}
}
throw exc;
/*
* A system exception would be highly unusual and would indicate a sever
* problem with the container system.
*/
} catch (final SystemException se) {
if (interfaceType.isLocal()) {
throw new EJBException("Container has suffered a SystemException").initCause(se.getRootCause());
} else {
throw new RemoteException("Container has suffered a SystemException", se.getRootCause());
}
} catch (final OpenEJBException oe) {
if (interfaceType.isLocal()) {
throw new EJBException("Unknown Container Exception").initCause(oe.getRootCause());
} else {
throw new RemoteException("Unknown Container Exception", oe.getRootCause());
}
} catch (final Throwable t) {
logger.debug("EjbHomeProxyHandler: finished invoking method " + method.getName() + " with exception:" + t, t);
throw t;
}
}
use of org.apache.openejb.InvalidateReferenceException in project tomee by apache.
the class ManagedContainer method removeEJBObject.
protected Object removeEJBObject(final BeanContext beanContext, final Object primKey, final Class callInterface, final Method callMethod, Object[] args, final InterfaceType interfaceType) throws OpenEJBException {
if (primKey == null) {
throw new NullPointerException("primKey is null");
}
final ThreadContext callContext = new ThreadContext(beanContext, primKey);
final ThreadContext oldCallContext = ThreadContext.enter(callContext);
try {
// Security check
final boolean internalRemove = BeanContext.Removable.class == callMethod.getDeclaringClass();
if (!internalRemove) {
checkAuthorization(callMethod, interfaceType);
}
// If a bean managed transaction is active, the bean can not be removed
if (interfaceType.isComponent()) {
final Instance instance = checkedOutInstances.get(primKey);
/**
* According to EJB 3.0 "4.4.4 Restrictions for Transactions" any remove methods
* from home or component interfaces must not be allowed if the bean instance is
* in a transaction. Unfortunately, the Java EE 5 TCK has tests that ignore the
* restrictions in 4.4.4 and expect beans in transactions can be removed via their
* home or component interface. The test to see if the bean instance implements
* javax.ejb.SessionBean is a workaround for passing the TCK while the tests in
* question can be challenged or the spec can be changed/updated.
*/
if (instance != null && instance.bean instanceof SessionBean) {
throw new ApplicationException(new RemoveException("A stateful EJB enrolled in a transaction can not be removed"));
}
}
// Start transaction
final TransactionPolicy txPolicy = EjbTransactionUtil.createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, interfaceType), callContext);
Object returnValue = null;
boolean retain = false;
Instance instance = null;
Method runMethod = null;
try {
// Obtain instance
instance = obtainInstance(primKey, callContext);
// Resume previous Bean transaction if there was one
if (txPolicy instanceof BeanTransactionPolicy) {
// Resume previous Bean transaction if there was one
final SuspendedTransaction suspendedTransaction = instance.getBeanTransaction();
if (suspendedTransaction != null) {
instance.setBeanTransaction(null);
final BeanTransactionPolicy beanTxEnv = (BeanTransactionPolicy) txPolicy;
beanTxEnv.resumeUserTransaction(suspendedTransaction);
}
}
if (!internalRemove) {
// Register the entity managers
registerEntityManagers(instance, callContext);
// Register for synchronization callbacks
registerSessionSynchronization(instance, callContext);
// Setup for remove invocation
callContext.setCurrentOperation(Operation.REMOVE);
callContext.setCurrentAllowedStates(null);
callContext.setInvokedInterface(callInterface);
runMethod = beanContext.getMatchingBeanMethod(callMethod);
callContext.set(Method.class, runMethod);
// Do not pass arguments on home.remove(remote) calls
final Class<?> declaringClass = callMethod.getDeclaringClass();
if (declaringClass.equals(EJBHome.class) || declaringClass.equals(EJBLocalHome.class)) {
args = new Object[] {};
}
// Initialize interceptor stack
final List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod);
final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, Operation.REMOVE, interceptors, instance.interceptors);
// Invoke
if (args == null) {
returnValue = interceptorStack.invoke();
} else {
returnValue = interceptorStack.invoke(args);
}
}
} catch (final InvalidateReferenceException e) {
throw new ApplicationException(e.getRootCause());
} catch (final Throwable e) {
if (interfaceType.isBusiness()) {
retain = beanContext.retainIfExeption(runMethod);
handleException(callContext, txPolicy, e);
} else {
try {
handleException(callContext, txPolicy, e);
} catch (final ApplicationException ae) {
// Don't throw application exceptions for non-business interface removes
}
}
} finally {
if (!retain) {
try {
callContext.setCurrentOperation(Operation.PRE_DESTROY);
final List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors();
final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, null, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
interceptorStack.invoke();
} catch (final Throwable callbackException) {
final String logMessage = "An unexpected exception occured while invoking the preDestroy method on the removed Stateful SessionBean instance; " + callbackException.getClass().getName() + " " + callbackException.getMessage();
/* [1] Log the exception or error */
logger.error(logMessage);
} finally {
callContext.setCurrentOperation(Operation.REMOVE);
}
// todo destroy extended persistence contexts
discardInstance(callContext);
}
// Commit transaction
afterInvoke(callContext, txPolicy, instance);
}
return returnValue;
} finally {
ThreadContext.exit(oldCallContext);
}
}
use of org.apache.openejb.InvalidateReferenceException in project tomee by apache.
the class EjbObjectProxyHandler method _invoke.
@Override
public Object _invoke(final Object p, final Class interfce, final Method m, final Object[] a) throws Throwable {
Object retValue = null;
Throwable exc = null;
final String methodName = m.getName();
try {
if (logger.isDebugEnabled()) {
logger.debug("EjbObjectProxyHandler: invoking method " + methodName + " on " + deploymentID + " with identity " + primaryKey);
}
Integer operation = dispatchTable.get(methodName);
if (operation != null) {
if (operation == 3) {
if (m.getParameterTypes()[0] != EJBObject.class && m.getParameterTypes()[0] != EJBLocalObject.class) {
operation = null;
}
} else {
operation = m.getParameterTypes().length == 0 ? operation : null;
}
}
if (operation == null || !interfaceType.isComponent()) {
retValue = businessMethod(interfce, m, a, p);
} else {
switch(operation) {
case 1:
retValue = getHandle(m, a, p);
break;
case 2:
retValue = getPrimaryKey(m, a, p);
break;
case 3:
retValue = isIdentical(m, a, p);
break;
case 4:
retValue = remove(interfce, m, a, p);
break;
case 5:
retValue = getEJBHome(m, a, p);
break;
case 6:
retValue = getEJBLocalHome(m, a, p);
break;
default:
throw new OpenEJBRuntimeException("Inconsistent internal state");
}
}
return retValue;
/*
* The ire is thrown by the container system and propagated by
* the server to the stub.
*/
} catch (final InvalidateReferenceException ire) {
invalidateAllHandlers(getRegistryId());
exc = ire.getRootCause() != null ? ire.getRootCause() : new RemoteException("InvalidateReferenceException: " + ire);
throw exc;
/*
* Application exceptions must be reported dirctly to the client. They
* do not impact the viability of the proxy.
*/
} catch (final ApplicationException ae) {
exc = ae.getRootCause() != null ? ae.getRootCause() : ae;
if (exc instanceof EJBAccessException) {
if (interfaceType.isBusiness()) {
throw exc;
} else {
if (interfaceType.isLocal()) {
throw new AccessLocalException(exc.getMessage()).initCause(exc.getCause());
} else {
throw new AccessException(exc.getMessage());
}
}
}
throw exc;
/*
* A system exception would be highly unusual and would indicate a sever
* problem with the container system.
*/
} catch (final SystemException se) {
invalidateReference();
exc = se.getRootCause() != null ? se.getRootCause() : se;
logger.debug("The container received an unexpected exception: ", exc);
throw new RemoteException("Container has suffered a SystemException", exc);
} catch (final OpenEJBException oe) {
exc = oe.getRootCause() != null ? oe.getRootCause() : oe;
logger.debug("The container received an unexpected exception: ", exc);
throw new RemoteException("Unknown Container Exception", oe.getRootCause());
} finally {
if (logger.isDebugEnabled()) {
if (exc == null) {
String ret = "void";
if (null != retValue) {
try {
ret = retValue.toString();
} catch (final Exception e) {
ret = "toString() failed on (" + e.getMessage() + ")";
}
}
logger.debug("EjbObjectProxyHandler: finished invoking method " + methodName + ". Return value:" + ret);
} else {
logger.debug("EjbObjectProxyHandler: finished invoking method " + methodName + " with exception " + exc);
}
}
}
}
use of org.apache.openejb.InvalidateReferenceException in project tomee by apache.
the class StatefulContainer method obtainInstance.
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
private Instance obtainInstance(final Object primaryKey, final ThreadContext callContext, final Method callMethod, final boolean checkOutIfNecessary) throws OpenEJBException {
if (primaryKey == null) {
throw new SystemException(new NullPointerException("Cannot obtain an instance of the stateful session bean with a null session id"));
}
final Transaction currentTransaction = getTransaction(callContext);
// Find the instance
Instance instance;
synchronized (this) {
instance = checkedOutInstances.get(primaryKey);
if (instance == null) {
// no need to check for extended persistence contexts it shouldn't happen
try {
instance = cache.checkOut(primaryKey, checkOutIfNecessary);
} catch (final OpenEJBException e) {
throw e;
} catch (final Exception e) {
throw new SystemException("Unexpected load exception", e);
}
// Did we find the instance?
if (instance == null) {
throw new InvalidateReferenceException(new NoSuchObjectException("Not Found"));
}
// remember instance until it is returned to the cache
checkedOutInstances.put(primaryKey, instance);
}
}
final Duration accessTimeout = getAccessTimeout(instance.beanContext, callMethod);
final LockFactory.StatefulLock currLock = instance.getLock();
final boolean lockAcquired;
if (accessTimeout == null || accessTimeout.getTime() < 0) {
// wait indefinitely for a lock
currLock.lock();
lockAcquired = true;
} else if (accessTimeout.getTime() == 0) {
// concurrent calls are not allowed, lock only once
lockAcquired = currLock.tryLock();
} else {
// try to get a lock within the specified period.
try {
lockAcquired = currLock.tryLock(accessTimeout.getTime(), accessTimeout.getUnit());
} catch (final InterruptedException e) {
throw new ApplicationException("Unable to get lock.", e);
}
}
// Did we acquire the lock to the current execution?
if (!lockAcquired) {
throw new ApplicationException(new ConcurrentAccessTimeoutException("Unable to get lock."));
}
if (instance.getTransaction() != null) {
if (!instance.getTransaction().equals(currentTransaction) && !instance.getLock().tryLock()) {
throw new ApplicationException(new RemoteException("Instance is in a transaction and cannot be invoked outside that transaction. See EJB 3.0 Section 4.4.4"));
}
} else {
instance.setTransaction(currentTransaction);
}
// Mark the instance in use so we can detect reentrant calls
instance.setInUse(true);
return instance;
}
use of org.apache.openejb.InvalidateReferenceException in project tomee by apache.
the class EjbTransactionUtil method handleSystemException.
/**
* Performs EJB rules when a system exception occurs.
*/
public static void handleSystemException(final TransactionPolicy txPolicy, final Throwable sysException, final ThreadContext callContext) throws InvalidateReferenceException {
// Log the system exception or error
Operation operation = null;
if (callContext != null) {
operation = callContext.getCurrentOperation();
}
if (operation != null) {
logger.error("EjbTransactionUtil.handleSystemException: " + sysException.getMessage(), sysException);
} else {
logger.debug("EjbTransactionUtil.handleSystemException: " + sysException.getMessage(), sysException);
}
// Mark the transaction for rollback
txPolicy.setRollbackOnly(sysException);
// Throw InvalidateReferenceException
if (txPolicy.isClientTransaction()) {
// using caller's transaction
final String message = "The transaction has been marked rollback only because the bean encountered a non-application exception :" + sysException.getClass().getName() + " : " + sysException.getMessage();
final TransactionRolledbackException txException = new TransactionRolledbackException(message, sysException);
throw new InvalidateReferenceException(txException);
} else {
// no transaction or in a new transaction for this method call
final RemoteException re = new RemoteException("The bean encountered a non-application exception", sysException);
throw new InvalidateReferenceException(re);
}
}
Aggregations