Search in sources :

Example 16 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class StatelessContainer method _invoke.

@SuppressWarnings("ThrowFromFinallyBlock")
private Object _invoke(final Method callMethod, final Method runMethod, final Object[] args, final Instance instance, final ThreadContext callContext, final InterfaceType type) throws OpenEJBException {
    final BeanContext beanContext = callContext.getBeanContext();
    final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);
    Object returnValue = null;
    try {
        if (type == InterfaceType.SERVICE_ENDPOINT) {
            callContext.setCurrentOperation(Operation.BUSINESS_WS);
            returnValue = invokeWebService(args, beanContext, runMethod, instance);
        } else {
            final List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod);
            final Operation operation = type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS;
            final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, operation, interceptors, instance.interceptors);
            returnValue = interceptorStack.invoke(args);
        }
    } catch (final Throwable re) {
        // handle reflection exception
        final ExceptionType exceptionType = beanContext.getExceptionType(re);
        if (exceptionType == ExceptionType.SYSTEM) {
            /* System Exception ****************************/
            // The bean instance is not put into the pool via instanceManager.poolInstance
            // and therefore the instance will be garbage collected and destroyed.
            // In case of StrictPooling flag being set to true we also release the semaphore
            // in the discardInstance method of the instanceManager.
            callContext.setDiscardInstance(true);
            handleSystemException(txPolicy, re, callContext);
        } else {
            /* Application Exception ***********************/
            handleApplicationException(txPolicy, re, exceptionType == ExceptionType.APPLICATION_ROLLBACK);
        }
    } finally {
        try {
            afterInvoke(txPolicy, callContext);
        } catch (final SystemException | RuntimeException e) {
            callContext.setDiscardInstance(true);
            throw e;
        }
    }
    return returnValue;
}
Also used : BeanContext(org.apache.openejb.BeanContext) ExceptionType(org.apache.openejb.core.ExceptionType) EjbTransactionUtil.handleSystemException(org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException) SystemException(org.apache.openejb.SystemException) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) EjbTransactionUtil.createTransactionPolicy(org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy) Operation(org.apache.openejb.core.Operation)

Example 17 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class StatefulContainer method createEJBObject.

protected ProxyInfo createEJBObject(final BeanContext beanContext, final Method callMethod, final Object[] args, final InterfaceType interfaceType) throws OpenEJBException {
    // generate a new primary key
    final Object primaryKey = newPrimaryKey();
    final ThreadContext createContext = new ThreadContext(beanContext, primaryKey);
    final ThreadContext oldCallContext = ThreadContext.enter(createContext);
    Object runAs = null;
    try {
        if (oldCallContext != null) {
            final BeanContext oldBc = oldCallContext.getBeanContext();
            if (oldBc.getRunAsUser() != null || oldBc.getRunAs() != null) {
                runAs = AbstractSecurityService.class.cast(securityService).overrideWithRunAsContext(createContext, beanContext, oldBc);
            }
        }
        // Security check
        checkAuthorization(callMethod, interfaceType);
        // Create the extended entity managers for this instance
        final Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = createEntityManagers(beanContext);
        // Register the newly created entity managers
        if (entityManagers != null) {
            try {
                entityManagerRegistry.addEntityManagers((String) beanContext.getDeploymentID(), primaryKey, entityManagers);
            } catch (final EntityManagerAlreadyRegisteredException e) {
                throw new EJBException(e);
            }
        }
        createContext.setCurrentOperation(Operation.CREATE);
        createContext.setCurrentAllowedStates(null);
        // Start transaction
        final TransactionPolicy txPolicy = EjbTransactionUtil.createTransactionPolicy(createContext.getBeanContext().getTransactionType(callMethod, interfaceType), createContext);
        Instance instance = null;
        try {
            try {
                final InstanceContext context = beanContext.newInstance();
                // Wrap-up everthing into a object
                instance = new Instance(beanContext, primaryKey, containerID, context.getBean(), context.getCreationalContext(), context.getInterceptors(), entityManagers, lockFactory.newLock(primaryKey.toString()));
            } catch (final Throwable throwable) {
                final ThreadContext callContext = ThreadContext.getThreadContext();
                EjbTransactionUtil.handleSystemException(callContext.getTransactionPolicy(), throwable, callContext);
                // should never be reached
                throw new IllegalStateException(throwable);
            }
            // add to cache
            if (isPassivable(beanContext)) {
                // no need to cache it it will never expires
                cache.add(primaryKey, instance);
            }
            // instance starts checked-out
            checkedOutInstances.put(primaryKey, instance);
            // Register for synchronization callbacks
            registerSessionSynchronization(instance, createContext);
            // Invoke create for legacy beans
            if (!callMethod.getDeclaringClass().equals(BeanContext.BusinessLocalHome.class) && !callMethod.getDeclaringClass().equals(BeanContext.BusinessRemoteHome.class) && !callMethod.getDeclaringClass().equals(BeanContext.BusinessLocalBeanHome.class)) {
                // Setup for business invocation
                final Method createOrInit = beanContext.getMatchingBeanMethod(callMethod);
                createContext.set(Method.class, createOrInit);
                // Initialize interceptor stack
                final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, createOrInit, Operation.CREATE, new ArrayList<InterceptorData>(), new HashMap<String, Object>());
                // Invoke
                if (args == null) {
                    interceptorStack.invoke();
                } else {
                    interceptorStack.invoke(args);
                }
            }
        } catch (final Throwable e) {
            handleException(createContext, txPolicy, e);
        } finally {
            // un register EntityManager
            unregisterEntityManagers(instance, createContext);
            afterInvoke(createContext, txPolicy, instance);
        }
        return new ProxyInfo(beanContext, primaryKey);
    } finally {
        if (runAs != null) {
            try {
                securityService.associate(runAs);
            } catch (final LoginException e) {
            // no-op
            }
        }
        ThreadContext.exit(oldCallContext);
    }
}
Also used : EntityManagerAlreadyRegisteredException(org.apache.openejb.persistence.EntityManagerAlreadyRegisteredException) SystemInstance(org.apache.openejb.loader.SystemInstance) 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) BeanContext(org.apache.openejb.BeanContext) ProxyInfo(org.apache.openejb.ProxyInfo) InstanceContext(org.apache.openejb.core.InstanceContext) EntityManagerFactory(javax.persistence.EntityManagerFactory) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) LoginException(javax.security.auth.login.LoginException) OpenEJBException(org.apache.openejb.OpenEJBException) EJBException(javax.ejb.EJBException)

Example 18 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class StatefulContainer method getTransaction.

private Transaction getTransaction(final ThreadContext callContext) {
    final TransactionPolicy policy = callContext.getTransactionPolicy();
    Transaction currentTransaction = null;
    if (policy instanceof JtaTransactionPolicy) {
        final JtaTransactionPolicy jtaPolicy = (JtaTransactionPolicy) policy;
        currentTransaction = jtaPolicy.getCurrentTransaction();
    }
    return currentTransaction;
}
Also used : Transaction(javax.transaction.Transaction) SuspendedTransaction(org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction) EjbUserTransaction(org.apache.openejb.core.transaction.EjbUserTransaction) JtaTransactionPolicy(org.apache.openejb.core.transaction.JtaTransactionPolicy) JtaTransactionPolicy(org.apache.openejb.core.transaction.JtaTransactionPolicy) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy)

Example 19 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class TransactionRule method apply.

@Override
public Statement apply(final Statement base, final Description description) {
    final Method mtd = getMethod(description.getTestClass(), description.getMethodName());
    final Transaction tx = mtd.getAnnotation(Transaction.class);
    if (tx != null) {
        return new Statement() {

            @Override
            public void evaluate() throws Throwable {
                final TransactionManager transactionManager = SystemInstance.get().getComponent(TransactionManager.class);
                final JtaTransactionPolicyFactory factory = new JtaTransactionPolicyFactory(transactionManager);
                final TransactionPolicy policy = factory.createTransactionPolicy(TransactionType.RequiresNew);
                try {
                    base.evaluate();
                } finally {
                    if (tx.rollback()) {
                        policy.setRollbackOnly();
                    }
                    policy.commit();
                }
            }
        };
    } else {
        return new Statement() {

            @Override
            public void evaluate() throws Throwable {
                base.evaluate();
            }
        };
    }
}
Also used : Statement(org.junit.runners.model.Statement) TransactionManager(javax.transaction.TransactionManager) JtaTransactionPolicyFactory(org.apache.openejb.core.transaction.JtaTransactionPolicyFactory) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) Method(java.lang.reflect.Method)

Example 20 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class EntityInstanceManager method poolInstance.

public void poolInstance(final ThreadContext callContext, final EntityBean bean, final Object primaryKey) throws OpenEJBException {
    if (bean == null) {
        return;
    }
    // primary key is null if its a servicing a home methods (create, find, ejbHome)
    final TransactionPolicy txPolicy = callContext.getTransactionPolicy();
    if (primaryKey != null && txPolicy != null && txPolicy.isTransactionActive()) {
        final Key key = new Key(callContext.getBeanContext().getDeploymentID(), primaryKey);
        SynchronizationWrapper wrapper = (SynchronizationWrapper) txPolicy.getResource(key);
        if (wrapper != null) {
            if (callContext.getCurrentOperation() == Operation.REMOVE) {
                /*
                    * The bean is being returned to the pool after it has been removed. Its
                    * important at this point to mark the bean as disassociated to prevent
                    * it's ejbStore method from bean called (see SynchronizationWrapper.beforeCompletion() method)
                    * and that subsequent methods can not be invoked on the bean identity (see obtainInstance() method).
                    */
                wrapper.disassociate();
                /*
                    * If the bean has been removed then the bean instance is no longer needed and can return to the methodReadyPool
                    * to service another identity.
                    */
                final Stack methodReadyPool = poolMap.get(callContext.getBeanContext().getDeploymentID());
                methodReadyPool.push(bean);
            } else {
                if (callContext.getCurrentOperation() == Operation.CREATE) {
                    // Bean is being recreated (new-delete-new) so we need to reassociate it
                    wrapper.associate();
                }
                wrapper.setEntityBean(bean);
            }
        } else {
            /*
                A wrapper will not exist if the bean is being returned after a create operation.
                In this case the transaction scope is broader then the create method itself; its a client
                initiated transaction, so the bean must be registered with the tranaction and moved to the
                tx ready pool
                */
            wrapper = new SynchronizationWrapper(callContext.getBeanContext(), primaryKey, bean, true, key, txPolicy);
            txPolicy.registerSynchronization(wrapper);
            txPolicy.putResource(key, wrapper);
        }
    } else {
        if (primaryKey != null && callContext.getCurrentOperation() != Operation.REMOVE) {
            /*
                * If the bean has a primary key; And its not being returned following a remove operation;
                * then the bean is being returned to the method ready pool after successfully executing a business method or create
                * method. In this case we need to call the bean instance's ejbPassivate before returning it to the pool per EJB 1.1
                * Section 9.1.
                */
            final Operation currentOp = callContext.getCurrentOperation();
            callContext.setCurrentOperation(Operation.PASSIVATE);
            try {
                /*
                    In the event of an exception, OpenEJB is required to log the exception, evict the instance,
                    and mark the transaction for rollback.  If there is a transaction to rollback, then the a
                    javax.transaction.TransactionRolledbackException must be throw to the client.
                    See EJB 1.1 specification, section 12.3.2
                    */
                bean.ejbPassivate();
            } catch (final Throwable e) {
                if (txPolicy.isTransactionActive()) {
                    txPolicy.setRollbackOnly(e);
                    throw new ApplicationException(new TransactionRolledbackException("Reflection exception thrown while attempting to call ejbPassivate() on the instance", e));
                }
                throw new ApplicationException(new RemoteException("Reflection exception thrown while attempting to call ejbPassivate() on the instance. Exception message = " + e.getMessage(), e));
            } finally {
                callContext.setCurrentOperation(currentOp);
            }
        }
        /*
            * The bean is returned to the method ready pool if its returned after servicing a find, ejbHome, business or create
            * method and is not still part of a tx.  While in the method ready pool the bean instance is not associated with a
            * primary key and may be used to service a request for any bean of the same class.
            */
        final Stack methodReadyPool = poolMap.get(callContext.getBeanContext().getDeploymentID());
        methodReadyPool.push(bean);
    }
}
Also used : ApplicationException(org.apache.openejb.ApplicationException) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) Operation(org.apache.openejb.core.Operation) TransactionRolledbackException(org.apache.openejb.core.transaction.TransactionRolledbackException) RemoteException(java.rmi.RemoteException) LinkedListStack(org.apache.openejb.util.LinkedListStack) Stack(org.apache.openejb.util.Stack)

Aggregations

TransactionPolicy (org.apache.openejb.core.transaction.TransactionPolicy)38 BeanContext (org.apache.openejb.BeanContext)26 EjbTransactionUtil.createTransactionPolicy (org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy)17 Method (java.lang.reflect.Method)14 EJBLocalObject (javax.ejb.EJBLocalObject)11 EJBObject (javax.ejb.EJBObject)11 EntityBean (javax.ejb.EntityBean)11 ThreadContext (org.apache.openejb.core.ThreadContext)10 InterceptorData (org.apache.openejb.core.interceptor.InterceptorData)10 InterceptorStack (org.apache.openejb.core.interceptor.InterceptorStack)10 BeanTransactionPolicy (org.apache.openejb.core.transaction.BeanTransactionPolicy)10 JtaTransactionPolicy (org.apache.openejb.core.transaction.JtaTransactionPolicy)10 ApplicationException (org.apache.openejb.ApplicationException)8 SystemInstance (org.apache.openejb.loader.SystemInstance)7 OpenEJBException (org.apache.openejb.OpenEJBException)6 ProxyInfo (org.apache.openejb.ProxyInfo)6 SystemException (org.apache.openejb.SystemException)6 Operation (org.apache.openejb.core.Operation)6 SuspendedTransaction (org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction)6 InvocationTargetException (java.lang.reflect.InvocationTargetException)5