Search in sources :

Example 1 with TransactionType

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

the class BeanContext method newInstance.

@SuppressWarnings("unchecked")
public InstanceContext newInstance() throws Exception {
    final boolean dynamicallyImplemented = isDynamicallyImplemented();
    final WebBeansContext webBeansContext = getWebBeansContext();
    if (dynamicallyImplemented) {
        if (!InvocationHandler.class.isAssignableFrom(getProxyClass())) {
            throw new OpenEJBException("proxy class can only be InvocationHandler");
        }
    }
    final ThreadContext callContext = new ThreadContext(this, null, Operation.INJECTION);
    final ThreadContext oldContext = ThreadContext.enter(callContext);
    try {
        final Context ctx = getJndiEnc();
        final Class beanClass = getBeanClass();
        final CurrentCreationalContext<Object> currentCreationalContext = get(CurrentCreationalContext.class);
        CreationalContext<Object> creationalContext = currentCreationalContext != null ? currentCreationalContext.get() : null;
        final CdiEjbBean cdiEjbBean = get(CdiEjbBean.class);
        if (!CreationalContextImpl.class.isInstance(creationalContext) && webBeansContext != null) {
            if (creationalContext == null) {
                creationalContext = webBeansContext.getCreationalContextFactory().getCreationalContext(cdiEjbBean);
            } else {
                creationalContext = webBeansContext.getCreationalContextFactory().wrappedCreationalContext(creationalContext, cdiEjbBean);
            }
        }
        final Object rootInstance;
        if (cdiEjbBean != null && !dynamicallyImplemented && CdiEjbBean.EjbInjectionTargetImpl.class.isInstance(cdiEjbBean.getInjectionTarget())) {
            rootInstance = CdiEjbBean.EjbInjectionTargetImpl.class.cast(cdiEjbBean.getInjectionTarget()).createNewPojo(creationalContext);
        } else {
            // not a cdi bean
            rootInstance = getManagedClass().newInstance();
        }
        // Create bean instance
        Object beanInstance;
        final InjectionProcessor injectionProcessor;
        if (!dynamicallyImplemented) {
            injectionProcessor = new InjectionProcessor(rootInstance, getInjections(), InjectionProcessor.unwrap(ctx));
            beanInstance = injectionProcessor.createInstance();
            inject(beanInstance, creationalContext);
        } else {
            // update target
            final List<Injection> newInjections = new ArrayList<>();
            for (final Injection injection : getInjections()) {
                if (beanClass.equals(injection.getTarget())) {
                    final Injection updated = new Injection(injection.getJndiName(), injection.getName(), proxyClass);
                    newInjections.add(updated);
                } else {
                    newInjections.add(injection);
                }
            }
            injections.clear();
            injections.addAll(newInjections);
            injectionProcessor = new InjectionProcessor(rootInstance, injections, InjectionProcessor.unwrap(ctx));
            final InvocationHandler handler = (InvocationHandler) injectionProcessor.createInstance();
            beanInstance = DynamicProxyImplFactory.newProxy(this, handler);
            inject(handler, creationalContext);
        }
        // Create interceptors
        final Map<String, Object> interceptorInstances = new LinkedHashMap<>();
        // Add the stats interceptor instance and other already created interceptor instances
        for (final InterceptorInstance interceptorInstance : this.getUserAndSystemInterceptors()) {
            final Class clazz = interceptorInstance.getData().getInterceptorClass();
            interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
        }
        final Collection<DependentCreationalContext<?>> createdDependents = getDependents(creationalContext);
        for (final InterceptorData interceptorData : this.getInstanceScopedInterceptors()) {
            if (interceptorData.getInterceptorClass().equals(beanClass)) {
                continue;
            }
            final Class clazz = interceptorData.getInterceptorClass();
            final Object iInstance;
            if (webBeansContext != null) {
                Object preInstantiated = null;
                if (createdDependents != null) {
                    for (final DependentCreationalContext<?> dcc : createdDependents) {
                        if (clazz.isInstance(dcc.getInstance())) {
                            // is that enough? do we have more to match?
                            preInstantiated = dcc.getInstance();
                            break;
                        }
                    }
                }
                if (preInstantiated != null) {
                    iInstance = preInstantiated;
                } else {
                    ConstructorInjectionBean interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
                    if (interceptorConstructor == null) {
                        synchronized (this) {
                            interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
                            if (interceptorConstructor == null) {
                                interceptorConstructor = new ConstructorInjectionBean(webBeansContext, clazz, webBeansContext.getAnnotatedElementFactory().newAnnotatedType(clazz));
                                interceptorData.set(ConstructorInjectionBean.class, interceptorConstructor);
                            }
                        }
                    }
                    CreationalContextImpl cc = (CreationalContextImpl) creationalContext;
                    Object oldDelegate = cc.putDelegate(beanInstance);
                    Bean<?> oldBean = cc.putBean(cdiEjbBean);
                    Contextual<?> oldContextual = cc.putContextual(interceptorData.getCdiInterceptorBean() != null ? interceptorData.getCdiInterceptorBean() : // otherwise BeanMetaData is broken
                    interceptorConstructor);
                    try {
                        iInstance = interceptorConstructor.create(creationalContext);
                    } finally {
                        cc.putBean(oldBean);
                        cc.putContextual(oldContextual);
                        cc.putDelegate(oldDelegate);
                    }
                }
            } else {
                iInstance = clazz.newInstance();
            }
            final InjectionProcessor interceptorInjector = new InjectionProcessor(iInstance, this.getInjections(), InjectionProcessor.unwrap(ctx));
            try {
                final Object interceptorInstance = interceptorInjector.createInstance();
                if (webBeansContext != null) {
                    try {
                        OWBInjector.inject(webBeansContext.getBeanManagerImpl(), interceptorInstance, creationalContext);
                    } catch (final Throwable t) {
                    // TODO handle this differently
                    // this is temporary till the injector can be rewritten
                    }
                }
                interceptorInstances.put(clazz.getName(), interceptorInstance);
            } catch (final ConstructionException e) {
                throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
            }
        }
        interceptorInstances.put(beanClass.getName(), beanInstance);
        // Invoke post construct method
        callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
        final List<InterceptorData> callbackInterceptors = this.getCallbackInterceptors();
        final InterceptorStack postConstruct = new InterceptorStack(beanInstance, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
        // Transaction Demarcation for Singleton PostConstruct method
        TransactionType transactionType;
        if (componentType == BeanType.SINGLETON || componentType == BeanType.STATEFUL) {
            final Set<Method> callbacks = callbackInterceptors.get(callbackInterceptors.size() - 1).getPostConstruct();
            if (callbacks.isEmpty()) {
                transactionType = TransactionType.RequiresNew;
            } else {
                // TODO: we should take the last one I think
                transactionType = getTransactionType(callbacks.iterator().next());
                if (transactionType == TransactionType.Required) {
                    transactionType = TransactionType.RequiresNew;
                }
            }
        } else {
            transactionType = isBeanManagedTransaction() ? TransactionType.BeanManaged : TransactionType.NotSupported;
        }
        final TransactionPolicy transactionPolicy = EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
        try {
            // Call the chain
            if (cdiEjbBean != null) {
                // call it, it has no postconstruct but extensions can add stuff here, TODO: see if it should be called before or after effective postconstruct
                cdiEjbBean.getInjectionTarget().postConstruct(beanInstance);
            }
            postConstruct.invoke();
        } catch (final Throwable e) {
            // RollBack Transaction
            EjbTransactionUtil.handleSystemException(transactionPolicy, e, callContext);
        } finally {
            EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
        }
        // handle cdi decorators
        if (cdiEjbBean != null) {
            final Class<?> proxyClass = Class.class.cast(Reflections.get(cdiEjbBean.getInjectionTarget(), "proxyClass"));
            if (proxyClass != null) {
                // means interception
                final InterceptorResolutionService.BeanInterceptorInfo interceptorInfo = cdiEjbBean.getBeanContext().get(InterceptorResolutionService.BeanInterceptorInfo.class);
                if (interceptorInfo.getDecorators() != null && !interceptorInfo.getDecorators().isEmpty()) {
                    final InterceptorDecoratorProxyFactory pf = webBeansContext.getInterceptorDecoratorProxyFactory();
                    // decorators
                    final Object instance = beanInstance;
                    final List<Decorator<?>> decorators = interceptorInfo.getDecorators();
                    final Map<Decorator<?>, Object> instances = new HashMap<>();
                    for (int i = decorators.size(); i > 0; i--) {
                        final Decorator<?> decorator = decorators.get(i - 1);
                        CreationalContextImpl cc = (CreationalContextImpl) creationalContext;
                        Object oldDelegate = cc.putDelegate(beanInstance);
                        Bean<?> oldBean = cc.putBean(cdiEjbBean);
                        // otherwise BeanMetaData is broken
                        Contextual<?> oldContextual = cc.putContextual(decorator);
                        Object decoratorInstance = null;
                        try {
                            decoratorInstance = decorator.create(CreationalContext.class.cast(creationalContext));
                        } finally {
                            cc.putBean(oldBean);
                            cc.putContextual(oldContextual);
                            cc.putDelegate(oldDelegate);
                        }
                        instances.put(decorator, decoratorInstance);
                        beanInstance = pf.createProxyInstance(proxyClass, instance, new DecoratorHandler(interceptorInfo, decorators, instances, i - 1, instance, cdiEjbBean.getId()));
                    }
                }
            }
        }
        return new InstanceContext(this, beanInstance, interceptorInstances, creationalContext);
    } finally {
        ThreadContext.exit(oldContext);
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) CreationalContextImpl(org.apache.webbeans.context.creational.CreationalContextImpl) LinkedHashMap(java.util.LinkedHashMap) InstanceContext(org.apache.openejb.core.InstanceContext) InterceptorInstance(org.apache.openejb.core.interceptor.InterceptorInstance) Method(java.lang.reflect.Method) AnnotatedMethod(javax.enterprise.inject.spi.AnnotatedMethod) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) TimedObject(javax.ejb.TimedObject) EJBLocalObject(javax.ejb.EJBLocalObject) EJBObject(javax.ejb.EJBObject) TransactionType(org.apache.openejb.core.transaction.TransactionType) CdiEjbBean(org.apache.openejb.cdi.CdiEjbBean) DecoratorHandler(org.apache.webbeans.intercept.DecoratorHandler) WebBeansContext(org.apache.webbeans.config.WebBeansContext) DependentCreationalContext(org.apache.webbeans.context.creational.DependentCreationalContext) WebBeansContext(org.apache.webbeans.config.WebBeansContext) CurrentCreationalContext(org.apache.openejb.cdi.CurrentCreationalContext) CreationalContext(javax.enterprise.context.spi.CreationalContext) Context(javax.naming.Context) DependentCreationalContext(org.apache.webbeans.context.creational.DependentCreationalContext) InstanceContext(org.apache.openejb.core.InstanceContext) ThreadContext(org.apache.openejb.core.ThreadContext) InterceptorResolutionService(org.apache.webbeans.intercept.InterceptorResolutionService) ConstructorInjectionBean(org.apache.openejb.cdi.ConstructorInjectionBean) ThreadContext(org.apache.openejb.core.ThreadContext) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) InvocationHandler(java.lang.reflect.InvocationHandler) ApplicationException(javax.ejb.ApplicationException) ConstructionException(org.apache.xbean.recipe.ConstructionException) Decorator(javax.enterprise.inject.spi.Decorator) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) ConstructionException(org.apache.xbean.recipe.ConstructionException) InterceptorDecoratorProxyFactory(org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory)

Example 2 with TransactionType

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

the class SingletonInstanceManager method freeInstance.

public void freeInstance(final ThreadContext callContext) {
    final BeanContext beanContext = callContext.getBeanContext();
    final Data data = (Data) beanContext.getContainerData();
    final Future<Instance> instanceFuture = data.singleton.get();
    // Possible the instance was never created
    if (instanceFuture == null) {
        return;
    }
    final Instance instance;
    try {
        instance = instanceFuture.get();
    } catch (final InterruptedException e) {
        Thread.interrupted();
        logger.error("Singleton shutdown failed because the thread was interrupted: " + beanContext.getDeploymentID(), e);
        return;
    } catch (final ExecutionException e) {
        // Instance was never initialized
        return;
    }
    try {
        callContext.setCurrentOperation(Operation.PRE_DESTROY);
        callContext.setCurrentAllowedStates(null);
        final Method remove = instance.bean instanceof SessionBean ? beanContext.getCreateMethod() : null;
        final List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors();
        final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
        // Transaction Demarcation for Singleton PostConstruct method
        TransactionType transactionType;
        if (beanContext.getComponentType() == BeanType.SINGLETON) {
            final Set<Method> callbacks = callbackInterceptors.get(callbackInterceptors.size() - 1).getPreDestroy();
            if (callbacks.isEmpty()) {
                transactionType = TransactionType.RequiresNew;
            } else {
                transactionType = beanContext.getTransactionType(callbacks.iterator().next());
                if (transactionType == TransactionType.Required) {
                    transactionType = TransactionType.RequiresNew;
                }
            }
        } else {
            transactionType = beanContext.isBeanManagedTransaction() ? TransactionType.BeanManaged : TransactionType.NotSupported;
        }
        final TransactionPolicy transactionPolicy = EjbTransactionUtil.createTransactionPolicy(transactionType, callContext);
        try {
            // Call the chain
            final CdiEjbBean<Object> bean = beanContext.get(CdiEjbBean.class);
            if (bean != null) {
                // TODO: see if it should be called before or after next call
                bean.getInjectionTarget().preDestroy(instance.bean);
            }
            interceptorStack.invoke();
            if (instance.creationalContext != null) {
                instance.creationalContext.release();
            }
        } catch (final Throwable e) {
            // RollBack Transaction
            EjbTransactionUtil.handleSystemException(transactionPolicy, e, callContext);
        } finally {
            EjbTransactionUtil.afterInvoke(transactionPolicy, callContext);
        }
    } catch (final Throwable re) {
        logger.error("Singleton shutdown failed: " + beanContext.getDeploymentID(), re);
    }
}
Also used : TransactionType(org.apache.openejb.core.transaction.TransactionType) SystemInstance(org.apache.openejb.loader.SystemInstance) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) Method(java.lang.reflect.Method) SessionBean(javax.ejb.SessionBean) BeanContext(org.apache.openejb.BeanContext) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with TransactionType

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

the class TransactionRule method apply.

@Override
public Statement apply(final Statement base, final Description description) {
    return new Statement() {

        @Override
        public void evaluate() throws Throwable {
            final TransactionAttribute annotation = description.getAnnotation(TransactionAttribute.class);
            final Transactional annotation2 = description.getAnnotation(Transactional.class);
            if (annotation == null && annotation2 == null) {
                base.evaluate();
                return;
            }
            final BeanContext beanContext = getBeanContext();
            final Method method = beanContext.getManagedClass().getMethod(description.getMethodName());
            final TransactionType transactionType = TransactionType.get(annotation == null ? TransactionAttributeType.valueOf(annotation2.value().name()) : annotation.value());
            beanContext.getMethodContext(method).setTransactionType(transactionType);
            ThreadContext tc = ThreadContext.getThreadContext();
            final boolean tcCreated;
            if (tc == null) {
                tcCreated = true;
                tc = ThreadContext.enter(new ThreadContext(beanContext, null));
            } else {
                tcCreated = false;
            }
            final TransactionPolicy policy = EjbTransactionUtil.createTransactionPolicy(transactionType, tc);
            try {
                base.evaluate();
            } finally {
                if (rollback) {
                    policy.setRollbackOnly();
                }
                EjbTransactionUtil.afterInvoke(policy, tc);
                if (tcCreated) {
                    ThreadContext.exit(tc);
                }
            }
        }
    };
}
Also used : BeanContext(org.apache.openejb.BeanContext) TransactionType(org.apache.openejb.core.transaction.TransactionType) TransactionAttribute(javax.ejb.TransactionAttribute) Statement(org.junit.runners.model.Statement) ThreadContext(org.apache.openejb.core.ThreadContext) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) Method(java.lang.reflect.Method) Transactional(javax.transaction.Transactional)

Aggregations

Method (java.lang.reflect.Method)3 TransactionPolicy (org.apache.openejb.core.transaction.TransactionPolicy)3 TransactionType (org.apache.openejb.core.transaction.TransactionType)3 BeanContext (org.apache.openejb.BeanContext)2 ThreadContext (org.apache.openejb.core.ThreadContext)2 InterceptorData (org.apache.openejb.core.interceptor.InterceptorData)2 InterceptorStack (org.apache.openejb.core.interceptor.InterceptorStack)2 InvocationHandler (java.lang.reflect.InvocationHandler)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutionException (java.util.concurrent.ExecutionException)1 ApplicationException (javax.ejb.ApplicationException)1 EJBLocalObject (javax.ejb.EJBLocalObject)1 EJBObject (javax.ejb.EJBObject)1 SessionBean (javax.ejb.SessionBean)1 TimedObject (javax.ejb.TimedObject)1 TransactionAttribute (javax.ejb.TransactionAttribute)1 CreationalContext (javax.enterprise.context.spi.CreationalContext)1