Search in sources :

Example 6 with ApplicationException

use of org.apache.openejb.ApplicationException 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);
    }
}
Also used : BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) SystemInstance(org.apache.openejb.loader.SystemInstance) EJBHome(javax.ejb.EJBHome) ThreadContext(org.apache.openejb.core.ThreadContext) JtaTransactionPolicy(org.apache.openejb.core.transaction.JtaTransactionPolicy) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) Method(java.lang.reflect.Method) SuspendedTransaction(org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction) SessionBean(javax.ejb.SessionBean) EJBLocalHome(javax.ejb.EJBLocalHome) BeanContext(org.apache.openejb.BeanContext) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) ApplicationException(org.apache.openejb.ApplicationException) RemoveException(javax.ejb.RemoveException) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack)

Example 7 with ApplicationException

use of org.apache.openejb.ApplicationException in project tomee by apache.

the class TxBeanManaged method commit.

public void commit() throws ApplicationException, SystemException {
    try {
        // The Container must detect the case in which a transaction was started, but
        // not completed, in the business method, and handle it as follows:
        final Transaction currentTx = getTransaction();
        if (currentTx != null) {
            final String message = "The EJB started a transaction but did not complete it.";
            /* [1] Log this as an application error ********/
            logger.error(message);
            /* [2] Roll back the started transaction *******/
            try {
                rollbackTransaction(currentTx);
            } catch (final Throwable t) {
            // no-op
            }
            /* [3] Throw the RemoteException to the client */
            throw new ApplicationException(new RemoteException(message));
        }
        fireNonTransactionalCompletion();
    } finally {
        resumeTransaction(clientTx);
    }
}
Also used : ApplicationException(org.apache.openejb.ApplicationException) Transaction(javax.transaction.Transaction) UserTransaction(javax.transaction.UserTransaction) CoreUserTransaction(org.apache.openejb.core.CoreUserTransaction) RemoteException(java.rmi.RemoteException)

Example 8 with ApplicationException

use of org.apache.openejb.ApplicationException 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;
}
Also used : OpenEJBException(org.apache.openejb.OpenEJBException) SystemInstance(org.apache.openejb.loader.SystemInstance) Duration(org.apache.openejb.util.Duration) LoginException(javax.security.auth.login.LoginException) NamingException(javax.naming.NamingException) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) EJBAccessException(javax.ejb.EJBAccessException) RemoveException(javax.ejb.RemoveException) ConcurrentAccessTimeoutException(javax.ejb.ConcurrentAccessTimeoutException) OpenEJBException(org.apache.openejb.OpenEJBException) RemoteException(java.rmi.RemoteException) EJBException(javax.ejb.EJBException) SystemException(org.apache.openejb.SystemException) NoSuchObjectException(java.rmi.NoSuchObjectException) EntityManagerAlreadyRegisteredException(org.apache.openejb.persistence.EntityManagerAlreadyRegisteredException) ApplicationException(org.apache.openejb.ApplicationException) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) ApplicationException(org.apache.openejb.ApplicationException) SystemException(org.apache.openejb.SystemException) Transaction(javax.transaction.Transaction) SuspendedTransaction(org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction) EjbUserTransaction(org.apache.openejb.core.transaction.EjbUserTransaction) NoSuchObjectException(java.rmi.NoSuchObjectException) ConcurrentAccessTimeoutException(javax.ejb.ConcurrentAccessTimeoutException) RemoteException(java.rmi.RemoteException)

Example 9 with ApplicationException

use of org.apache.openejb.ApplicationException in project tomee by apache.

the class MdbContainer method beforeDelivery.

public void beforeDelivery(final BeanContext deployInfo, final Object instance, final Method method, final XAResource xaResource) throws SystemException {
    // intialize call context
    final ThreadContext callContext = new ThreadContext(deployInfo, null);
    final ThreadContext oldContext = ThreadContext.enter(callContext);
    // create mdb context
    final MdbCallContext mdbCallContext = new MdbCallContext();
    callContext.set(MdbCallContext.class, mdbCallContext);
    mdbCallContext.deliveryMethod = method;
    mdbCallContext.oldCallContext = oldContext;
    // call the tx before method
    try {
        mdbCallContext.txPolicy = createTransactionPolicy(deployInfo.getTransactionType(method), callContext);
        // if we have an xaResource and a transaction was not imported from the adapter, enlist the xaResource
        if (xaResource != null && mdbCallContext.txPolicy.isNewTransaction()) {
            mdbCallContext.txPolicy.enlistResource(xaResource);
        }
    } catch (final ApplicationException e) {
        ThreadContext.exit(oldContext);
        throw new SystemException("Should never get an Application exception", e);
    } catch (final SystemException e) {
        ThreadContext.exit(oldContext);
        throw e;
    } catch (final Exception e) {
        ThreadContext.exit(oldContext);
        throw new SystemException("Unable to enlist xa resource in the transaction", e);
    }
}
Also used : EjbTransactionUtil.handleApplicationException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException) ApplicationException(org.apache.openejb.ApplicationException) SystemException(org.apache.openejb.SystemException) EjbTransactionUtil.handleSystemException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException) ThreadContext(org.apache.openejb.core.ThreadContext) ResourceException(javax.resource.ResourceException) NamingException(javax.naming.NamingException) OpenEJBException(org.apache.openejb.OpenEJBException) UnavailableException(javax.resource.spi.UnavailableException) InvocationTargetException(java.lang.reflect.InvocationTargetException) SystemException(org.apache.openejb.SystemException) EjbTransactionUtil.handleApplicationException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException) EjbTransactionUtil.handleSystemException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException) ApplicationException(org.apache.openejb.ApplicationException) ConstraintViolationException(javax.validation.ConstraintViolationException)

Example 10 with ApplicationException

use of org.apache.openejb.ApplicationException in project tomee by apache.

the class EjbMethodInvoker method preEjbInvoke.

private Object preEjbInvoke(Exchange exchange, Method method, List<Object> params) {
    EjbMessageContext ctx = new EjbMessageContext(exchange.getInMessage(), Scope.APPLICATION);
    WebServiceContextImpl.setMessageContext(ctx);
    Map<String, Object> handlerProperties = removeHandlerProperties(ctx);
    exchange.put(HANDLER_PROPERTIES, handlerProperties);
    try {
        EjbInterceptor interceptor = new EjbInterceptor(params, method, this.bus, exchange);
        Object[] arguments = { ctx, interceptor };
        RpcContainer container = (RpcContainer) this.beanContext.getContainer();
        Class callInterface = this.beanContext.getServiceEndpointInterface();
        method = getMostSpecificMethod(beanContext, method, callInterface);
        Object res = container.invoke(this.beanContext.getDeploymentID(), InterfaceType.SERVICE_ENDPOINT, callInterface, method, arguments, null);
        if (exchange.isOneWay()) {
            return null;
        }
        return new MessageContentsList(res);
    } catch (ApplicationException e) {
        // when no handler is defined, EjbInterceptor will directly delegate
        // to #directEjbInvoke. So if an application exception is thrown by
        // the end user, when must consider the ApplicationException as a
        // web fault if it contains the @WebFault exception
        Throwable t = e.getCause();
        if (t != null) {
            if (RuntimeException.class.isAssignableFrom(t.getClass()) && t.getClass().isAnnotationPresent(javax.ejb.ApplicationException.class)) {
                // it's not a checked exception so it can not be a WebFault
                throw (RuntimeException) t;
            } else if (!t.getClass().isAnnotationPresent(WebFault.class)) {
                // not a web fault even if it's an EJB ApplicationException
                exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
                throw createFault(t, method, params, false);
            }
        } else {
            // may not occurs ...
            t = e;
        }
        // TODO may be we can change to FaultMode.CHECKED_APPLICATION_FAULT
        exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
        throw createFault(t, method, params, false);
    } catch (Exception e) {
        exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
        throw createFault(e, method, params, false);
    } finally {
        WebServiceContextImpl.clear();
    }
}
Also used : MessageContentsList(org.apache.cxf.message.MessageContentsList) ApplicationException(org.apache.openejb.ApplicationException) WebFault(javax.xml.ws.WebFault) FaultMode(org.apache.cxf.message.FaultMode) RpcContainer(org.apache.openejb.RpcContainer) ApplicationException(org.apache.openejb.ApplicationException)

Aggregations

ApplicationException (org.apache.openejb.ApplicationException)26 OpenEJBException (org.apache.openejb.OpenEJBException)12 SystemException (org.apache.openejb.SystemException)11 BeanContext (org.apache.openejb.BeanContext)10 RemoteException (java.rmi.RemoteException)8 EJBAccessException (javax.ejb.EJBAccessException)7 InvalidateReferenceException (org.apache.openejb.InvalidateReferenceException)7 ThreadContext (org.apache.openejb.core.ThreadContext)7 EjbTransactionUtil.handleApplicationException (org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException)7 Method (java.lang.reflect.Method)6 Operation (org.apache.openejb.core.Operation)6 SystemInstance (org.apache.openejb.loader.SystemInstance)6 InvocationTargetException (java.lang.reflect.InvocationTargetException)5 EjbTransactionUtil.handleSystemException (org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException)5 EJBException (javax.ejb.EJBException)4 EJBHome (javax.ejb.EJBHome)4 EJBLocalHome (javax.ejb.EJBLocalHome)4 RemoveException (javax.ejb.RemoveException)4 NamingException (javax.naming.NamingException)4 InterceptorData (org.apache.openejb.core.interceptor.InterceptorData)4