use of org.apache.openejb.core.InstanceContext 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);
}
}
use of org.apache.openejb.core.InstanceContext 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<>(), new HashMap<>());
// 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);
}
}
use of org.apache.openejb.core.InstanceContext in project tomee by apache.
the class SingletonInstanceManager method createInstance.
private Instance createInstance(final ThreadContext callContext, final BeanContext beanContext) throws ApplicationException {
try {
initializeDependencies(beanContext);
final InstanceContext context = beanContext.newInstance();
if (context.getBean() instanceof SessionBean) {
final Operation originalOperation = callContext.getCurrentOperation();
try {
callContext.setCurrentOperation(Operation.CREATE);
final Method create = beanContext.getCreateMethod();
final InterceptorStack ejbCreate = new InterceptorStack(context.getBean(), create, Operation.CREATE, new ArrayList<>(), new HashMap());
ejbCreate.invoke();
} finally {
callContext.setCurrentOperation(originalOperation);
}
}
final ReadWriteLock lock;
if (beanContext.isBeanManagedConcurrency()) {
// Bean-Managed Concurrency
lock = new BeanManagedLock();
} else {
// Container-Managed Concurrency
lock = new ReentrantReadWriteLock();
}
return new Instance(context.getBean(), context.getInterceptors(), context.getCreationalContext(), lock);
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException) e).getTargetException();
}
final String t = "The bean instance " + beanContext.getDeploymentID() + " threw a system exception:" + e;
logger.error(t, e);
throw new ApplicationException(new NoSuchEJBException("Singleton failed to initialize").initCause(e));
}
}
use of org.apache.openejb.core.InstanceContext in project tomee by apache.
the class ManagedContainer 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);
try {
// 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, context.getBean(), context.getInterceptors(), context.getCreationalContext(), entityManagers);
} 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
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<>(), new HashMap<>());
// Invoke
if (args == null) {
interceptorStack.invoke();
} else {
interceptorStack.invoke(args);
}
}
} catch (final Throwable e) {
handleException(createContext, txPolicy, e);
} finally {
afterInvoke(createContext, txPolicy, instance);
}
return new ProxyInfo(beanContext, primaryKey);
} finally {
ThreadContext.exit(oldCallContext);
}
}
use of org.apache.openejb.core.InstanceContext in project tomee by apache.
the class MdbInstanceFactory method constructBean.
private Object constructBean() throws UnavailableException {
final BeanContext beanContext = this.beanContext;
final ThreadContext callContext = new ThreadContext(beanContext, null, Operation.INJECTION);
final ThreadContext oldContext = ThreadContext.enter(callContext);
try {
final InstanceContext context = beanContext.newInstance();
if (context.getBean() instanceof MessageDrivenBean) {
callContext.setCurrentOperation(Operation.CREATE);
final Method create = beanContext.getCreateMethod();
final InterceptorStack ejbCreate = new InterceptorStack(context.getBean(), create, Operation.CREATE, new ArrayList(), new HashMap());
ejbCreate.invoke();
}
return new Instance(context.getBean(), context.getInterceptors(), context.getCreationalContext());
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException) e).getTargetException();
}
final String message = "The bean instance threw a system exception:" + e;
MdbInstanceFactory.logger.error(message, e);
throw new UnavailableException(message, e);
} finally {
ThreadContext.exit(oldContext);
}
}
Aggregations