protected Object businessMethod( BeanContext beanContext, Object primKey, Class callInterface, Method callMethod, Object[] args, InterfaceType interfaceType) throws OpenEJBException { ThreadContext callContext = new ThreadContext(beanContext, primKey); ThreadContext oldCallContext = ThreadContext.enter(callContext); try { // Security check checkAuthorization(callMethod, interfaceType); // Start transaction TransactionPolicy txPolicy = createTransactionPolicy( callContext.getBeanContext().getTransactionType(callMethod, interfaceType), callContext); Object returnValue = null; Instance instance = null; try { // Obtain instance instance = obtainInstance(primKey, callContext); // Resume previous Bean transaction if there was one if (txPolicy instanceof BeanTransactionPolicy) { SuspendedTransaction suspendedTransaction = instance.getBeanTransaction(); if (suspendedTransaction != null) { instance.setBeanTransaction(null); BeanTransactionPolicy beanTxEnv = (BeanTransactionPolicy) txPolicy; beanTxEnv.resumeUserTransaction(suspendedTransaction); } } // Register the entity managers registerEntityManagers(instance, callContext); // Register for synchronization callbacks registerSessionSynchronization(instance, callContext); // Setup for business invocation callContext.setCurrentOperation(Operation.BUSINESS); callContext.setCurrentAllowedStates(null); callContext.setInvokedInterface(callInterface); Method runMethod = beanContext.getMatchingBeanMethod(callMethod); callContext.set(Method.class, runMethod); // Initialize interceptor stack List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, runMethod, Operation.BUSINESS, interceptors, instance.interceptors); // Invoke returnValue = interceptorStack.invoke(args); } catch (Throwable e) { handleException(callContext, txPolicy, e); } finally { // Commit transaction afterInvoke(callContext, txPolicy, instance); } return returnValue; } finally { ThreadContext.exit(oldCallContext); } }
public Object invoke( Object deployID, InterfaceType type, Class callInterface, Method callMethod, Object[] args, Object primKey) throws OpenEJBException { BeanContext beanContext = this.getBeanContext(deployID); if (beanContext == null) throw new OpenEJBException( "Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')"); // Use the backup way to determine call type if null was supplied. if (type == null) type = beanContext.getInterfaceType(callInterface); Method runMethod = beanContext.getMatchingBeanMethod(callMethod); ThreadContext callContext = new ThreadContext(beanContext, primKey); ThreadContext oldCallContext = ThreadContext.enter(callContext); Object bean = null; try { boolean authorized = type == InterfaceType.TIMEOUT || getSecurityService().isCallerAuthorized(callMethod, type); if (!authorized) throw new org.apache.openejb.ApplicationException( new EJBAccessException("Unauthorized Access by Principal Denied")); Class declaringClass = callMethod.getDeclaringClass(); if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) { if (callMethod.getName().startsWith("create")) { return createEJBObject(beanContext, callMethod); } else return null; // EJBHome.remove( ) and other EJBHome methods are not process by the // container } else if (EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) { return null; // EJBObject.remove( ) and other EJBObject methods are not process by the // container } bean = instanceManager.getInstance(callContext); callContext.setCurrentOperation( type == InterfaceType.TIMEOUT ? Operation.TIMEOUT : Operation.BUSINESS); callContext.set(Method.class, runMethod); callContext.setInvokedInterface(callInterface); Object retValue = _invoke(callMethod, runMethod, args, (Instance) bean, callContext, type); return retValue; } finally { if (bean != null) { if (callContext.isDiscardInstance()) { instanceManager.discardInstance(callContext, bean); } else { instanceManager.poolInstance(callContext, bean); } } ThreadContext.exit(oldCallContext); } }
protected Object removeEJBObject( BeanContext beanContext, Object primKey, Class callInterface, Method callMethod, Object[] args, InterfaceType interfaceType) throws OpenEJBException { if (primKey == null) throw new NullPointerException("primKey is null"); ThreadContext callContext = new ThreadContext(beanContext, primKey); ThreadContext oldCallContext = ThreadContext.enter(callContext); try { // Security check checkAuthorization(callMethod, interfaceType); // If a bean managed transaction is active, the bean can not be removed if (interfaceType.isComponent()) { 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 javax.ejb.SessionBean) { throw new ApplicationException( new RemoveException("A stateful EJB enrolled in a transaction can not be removed")); } } // Start transaction TransactionPolicy txPolicy = 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 SuspendedTransaction suspendedTransaction = instance.getBeanTransaction(); if (suspendedTransaction != null) { instance.setBeanTransaction(null); BeanTransactionPolicy beanTxEnv = (BeanTransactionPolicy) txPolicy; beanTxEnv.resumeUserTransaction(suspendedTransaction); } } // 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 Class<?> declaringClass = callMethod.getDeclaringClass(); if (declaringClass.equals(EJBHome.class) || declaringClass.equals(EJBLocalHome.class)) { args = new Object[] {}; } // Initialize interceptor stack List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod); 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 (InvalidateReferenceException e) { throw e; } catch (Throwable e) { if (interfaceType.isBusiness()) { retain = beanContext.retainIfExeption(runMethod); handleException(callContext, txPolicy, e); } else { try { handleException(callContext, txPolicy, e); } catch (ApplicationException ae) { // Don't throw application exceptions for non-business interface removes } } } finally { if (!retain) { try { callContext.setCurrentOperation(Operation.PRE_DESTROY); List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, null, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors); interceptorStack.invoke(); } catch (Throwable callbackException) { 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); } }
protected ProxyInfo createEJBObject( BeanContext beanContext, Method callMethod, Object[] args, InterfaceType interfaceType) throws OpenEJBException { // generate a new primary key Object primaryKey = newPrimaryKey(); ThreadContext createContext = new ThreadContext(beanContext, primaryKey); ThreadContext oldCallContext = ThreadContext.enter(createContext); try { // Security check checkAuthorization(callMethod, interfaceType); // Create the extended entity managers for this instance 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 (EntityManagerAlreadyRegisteredException e) { throw new EJBException(e); } } createContext.setCurrentOperation(Operation.CREATE); createContext.setCurrentAllowedStates(null); // Start transaction TransactionPolicy txPolicy = createTransactionPolicy( createContext.getBeanContext().getTransactionType(callMethod, interfaceType), createContext); Instance instance = null; try { // Create new instance 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 (Throwable throwable) { ThreadContext callContext = ThreadContext.getThreadContext(); handleSystemException(callContext.getTransactionPolicy(), throwable, callContext); throw new IllegalStateException(throwable); // should never be reached } // 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 Method createOrInit = beanContext.getMatchingBeanMethod(callMethod); createContext.set(Method.class, createOrInit); // Initialize interceptor stack 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 (Throwable e) { handleException(createContext, txPolicy, e); } finally { afterInvoke(createContext, txPolicy, instance); } return new ProxyInfo(beanContext, primaryKey); } finally { ThreadContext.exit(oldCallContext); } }
private ProxyInfo createEJBObject( final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType interfaceType) throws OpenEJBException { final BeanContext beanContext = callContext.getBeanContext(); final TransactionPolicy txPolicy = createTransactionPolicy( beanContext.getTransactionType(callMethod, interfaceType), callContext); final EntityBean bean; Object primaryKey = null; try { // Obtain a bean instance from the method ready pool bean = createNewInstance(callContext); // set the entity context setEntityContext(bean); // Obtain the proper ejbCreate() method final Method ejbCreateMethod = beanContext.getMatchingBeanMethod(callMethod); // Set current operation for allowed operations callContext.setCurrentOperation(Operation.CREATE); // Invoke the proper ejbCreate() method on the instance ejbCreateMethod.invoke(bean, args); // create the new bean primaryKey = cmpEngine.createBean(bean, callContext); // determine post create callback method final Method ejbPostCreateMethod = beanContext.getMatchingPostCreateMethod(ejbCreateMethod); // create a new context containing the pk for the post create call final ThreadContext postCreateContext = new ThreadContext(beanContext, primaryKey); postCreateContext.setCurrentOperation(Operation.POST_CREATE); final ThreadContext oldContext = ThreadContext.enter(postCreateContext); try { // Invoke the ejbPostCreate method on the bean instance ejbPostCreateMethod.invoke(bean, args); // According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...) // method executes in the same transaction context as the previous ejbCreate(...) method." // // The bean is first insterted using db.create( ) and then after ejbPostCreate( ) its // updated using db.update(). This protocol allows for visablity of the bean after ejbCreate // within the current trasnaction. } finally { ThreadContext.exit(oldContext); } // when there is not transaction, merge the data from the bean back into the cmp engine cmpEngine.storeBeanIfNoTx(callContext, bean); } catch (Throwable e) { if (e instanceof InvocationTargetException) { e = ((InvocationTargetException) e).getTargetException(); } final ExceptionType type = callContext.getBeanContext().getExceptionType(e); if (type == ExceptionType.SYSTEM) { /* System Exception ****************************/ handleSystemException(txPolicy, e, callContext); } else { /* Application Exception ***********************/ handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK); } } finally { afterInvoke(txPolicy, callContext); } return new ProxyInfo(beanContext, primaryKey); }
private Object homeMethod( final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType interfaceType) throws OpenEJBException { final BeanContext beanContext = callContext.getBeanContext(); final TransactionPolicy txPolicy = createTransactionPolicy( beanContext.getTransactionType(callMethod, interfaceType), callContext); final EntityBean bean; Object returnValue = null; try { /* Obtain a bean instance from the method ready pool */ bean = createNewInstance(callContext); // set the entity context setEntityContext(bean); try { callContext.setCurrentOperation(Operation.HOME); final Method runMethod = beanContext.getMatchingBeanMethod(callMethod); try { returnValue = runMethod.invoke(bean, args); } catch (final IllegalArgumentException e) { System.out.println("********************************************************"); System.out.println("callMethod = " + callMethod); System.out.println("runMethod = " + runMethod); System.out.println("bean = " + bean.getClass().getName()); throw e; } } finally { unsetEntityContext(bean); } } catch (Throwable e) { if (e instanceof InvocationTargetException) { e = ((InvocationTargetException) e).getTargetException(); } final ExceptionType type = callContext.getBeanContext().getExceptionType(e); if (type == ExceptionType.SYSTEM) { /* System Exception ****************************/ handleSystemException(txPolicy, e, callContext); } else { /* Application Exception ***********************/ handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK); } } finally { afterInvoke(txPolicy, callContext); } return returnValue; }
@Override public Object invoke( final Object deployID, InterfaceType type, final Class callInterface, final Method callMethod, final Object[] args, final Object primKey) throws OpenEJBException { final BeanContext beanContext = this.getBeanContext(deployID); if (beanContext == null) { throw new OpenEJBException( "Deployment does not exist in this container. Deployment(id='" + deployID + "'), Container(id='" + containerID + "')"); } // Use the backup way to determine call type if null was supplied. if (type == null) { type = beanContext.getInterfaceType(callInterface); } final ThreadContext callContext = new ThreadContext(beanContext, primKey); final ThreadContext oldCallContext = ThreadContext.enter(callContext); try { final boolean authorized = securityService.isCallerAuthorized(callMethod, type); if (!authorized) { throw new ApplicationException( new EJBAccessException("Unauthorized Access by Principal Denied")); } final Class declaringClass = callMethod.getDeclaringClass(); final String methodName = callMethod.getName(); if (EJBHome.class.isAssignableFrom(declaringClass) || EJBLocalHome.class.isAssignableFrom(declaringClass)) { if (declaringClass != EJBHome.class && declaringClass != EJBLocalHome.class) { if (methodName.startsWith("create")) { return createEJBObject(callMethod, args, callContext, type); } else if (methodName.equals("findByPrimaryKey")) { return findByPrimaryKey(callMethod, args, callContext, type); } else if (methodName.startsWith("find")) { return findEJBObject(callMethod, args, callContext, type); } else { return homeMethod(callMethod, args, callContext, type); } } else if (methodName.equals("remove")) { removeEJBObject(callMethod, callContext, type); return null; } } else if ((EJBObject.class == declaringClass || EJBLocalObject.class == declaringClass) && methodName.equals("remove")) { removeEJBObject(callMethod, callContext, type); return null; } // business method callContext.setCurrentOperation(Operation.BUSINESS); final Method runMethod = beanContext.getMatchingBeanMethod(callMethod); callContext.set(Method.class, runMethod); return businessMethod(callMethod, runMethod, args, callContext, type); } finally { ThreadContext.exit(oldCallContext); } }