private Object findByPrimaryKey( 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); try { final EntityBean bean = (EntityBean) cmpEngine.loadBean(callContext, args[0]); if (bean == null) { throw new ObjectNotFoundException(beanContext.getDeploymentID() + " : " + args[0]); } // rebuild the primary key final KeyGenerator kg = beanContext.getKeyGenerator(); final Object primaryKey = kg.getPrimaryKey(bean); // create a new ProxyInfo based on the deployment info and primary key return new ProxyInfo(beanContext, primaryKey); } catch (final FinderException fe) { handleApplicationException(txPolicy, fe, false); } catch (final Throwable e) { // handle reflection exception handleSystemException(txPolicy, e, callContext); } finally { afterInvoke(txPolicy, callContext); } throw new AssertionError("Should not get here"); }
public void timedOut(Instance instance) { BeanContext beanContext = instance.beanContext; ThreadContext threadContext = new ThreadContext(beanContext, instance.primaryKey, Operation.PRE_DESTROY); threadContext.setCurrentAllowedStates(null); ThreadContext oldContext = ThreadContext.enter(threadContext); try { Method remove = instance.bean instanceof SessionBean ? SessionBean.class.getMethod("ejbRemove") : null; List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors); interceptorStack.invoke(); } catch (Throwable e) { logger.error( "An unexpected exception occured while invoking the ejbRemove method on the timed-out Stateful SessionBean instance", e); } finally { logger.info("Removing the timed-out stateful session bean instance " + instance.primaryKey); ThreadContext.exit(oldContext); } }
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); Data data = (Data) beanContext.getContainerData(); MethodType methodType = data.getMethodIndex().get(callMethod); methodType = (methodType != null) ? methodType : MethodType.BUSINESS; switch (methodType) { case CREATE: return createEJBObject(beanContext, callMethod, args, type); case REMOVE: return removeEJBObject(beanContext, primKey, callInterface, callMethod, args, type); default: return businessMethod(beanContext, primKey, callInterface, callMethod, args, type); } }
public void afterLoad(Instance instance) throws SystemException, ApplicationException { BeanContext beanContext = instance.beanContext; ThreadContext threadContext = new ThreadContext(instance.beanContext, instance.primaryKey, Operation.ACTIVATE); ThreadContext oldContext = ThreadContext.enter(threadContext); try { Method remove = instance.bean instanceof SessionBean ? SessionBean.class.getMethod("ejbActivate") : null; List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, remove, Operation.ACTIVATE, callbackInterceptors, instance.interceptors); interceptorStack.invoke(); } catch (Throwable callbackException) { discardInstance(threadContext); handleSystemException( threadContext.getTransactionPolicy(), callbackException, threadContext); } finally { ThreadContext.exit(oldContext); } }
private void removeEJBObject( final Method callMethod, final ThreadContext callContext, final InterfaceType interfaceType) throws OpenEJBException { final BeanContext beanContext = callContext.getBeanContext(); final TransactionPolicy txPolicy = createTransactionPolicy( beanContext.getTransactionType(callMethod, interfaceType), callContext); try { final EntityBean entityBean = (EntityBean) cmpEngine.loadBean(callContext, callContext.getPrimaryKey()); if (entityBean == null) { throw new NoSuchObjectException( callContext.getBeanContext().getDeploymentID() + " " + callContext.getPrimaryKey()); } ejbRemove(entityBean); cmpEngine.removeBean(callContext); } catch (final NoSuchObjectException e) { handleApplicationException(txPolicy, e, false); } catch (final Throwable e) { // handle reflection exception handleSystemException(txPolicy, e, callContext); } finally { afterInvoke(txPolicy, callContext); } }
public void beforeStore(Instance instance) { BeanContext beanContext = instance.beanContext; ThreadContext threadContext = new ThreadContext(beanContext, instance.primaryKey, Operation.PASSIVATE); ThreadContext oldContext = ThreadContext.enter(threadContext); try { Method passivate = instance.bean instanceof SessionBean ? SessionBean.class.getMethod("ejbPassivate") : null; List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, passivate, Operation.PASSIVATE, callbackInterceptors, instance.interceptors); interceptorStack.invoke(); } catch (Throwable e) { logger.error( "An unexpected exception occured while invoking the ejbPassivate method on the Stateful SessionBean instance", e); } finally { ThreadContext.exit(oldContext); } }
private EntityBean createNewInstance(final ThreadContext callContext) { final BeanContext beanContext = callContext.getBeanContext(); try { return (EntityBean) beanContext.getCmpImplClass().newInstance(); } catch (final Exception e) { throw new EJBException( "Unable to create new entity bean instance " + beanContext.getCmpImplClass(), e); } }
public SingletonContainer(Object id, SecurityService securityService) throws OpenEJBException { this.containerID = id; this.securityService = securityService; instanceManager = new SingletonInstanceManager(securityService); for (BeanContext beanContext : deploymentRegistry.values()) { beanContext.setContainer(this); } }
private Duration getAccessTimeout(BeanContext beanContext, Method callMethod) { Duration accessTimeout = beanContext.getAccessTimeout(callMethod); if (accessTimeout == null) { accessTimeout = beanContext.getAccessTimeout(); if (accessTimeout == null) { accessTimeout = this.accessTimeout; } } return accessTimeout; }
private void unregisterEntityManagers(Instance instance, ThreadContext callContext) { if (entityManagerRegistry == null) return; if (instance == null) return; BeanContext beanContext = callContext.getBeanContext(); // register them entityManagerRegistry.removeEntityManagers( (String) beanContext.getDeploymentID(), instance.primaryKey); }
public void afterCompletion(Status status) { Throwable firstException = null; for (Synchronization synchronization : registry.values()) { Instance instance = synchronization.instance; ThreadContext callContext = new ThreadContext( instance.beanContext, instance.primaryKey, Operation.AFTER_COMPLETION); callContext.setCurrentAllowedStates(null); ThreadContext oldCallContext = ThreadContext.enter(callContext); try { instance.setInUse(true); if (synchronization.isCallSessionSynchronization()) { BeanContext beanContext = instance.beanContext; List<InterceptorData> interceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, null, Operation.AFTER_COMPLETION, interceptors, instance.interceptors); interceptorStack.invoke(status == Status.COMMITTED); } instance.setTransaction(null); releaseInstance(instance); } catch (InvalidateReferenceException inv) { // exception has alredy been handled } catch (Throwable e) { String message = "An unexpected system exception occured while invoking the afterCompletion method on the SessionSynchronization object"; // [1] Log the exception or error logger.error(message, e); // Transaction is complete so can not be rolled back // [3] Discard the instance discardInstance(callContext); // [4] throw throw first exception to the client if (firstException == null) firstException = e; } finally { ThreadContext.exit(oldCallContext); } } if (firstException != null) { throw new RuntimeException( "An unexpected system exception occured while invoking the afterCompletion method on the SessionSynchronization object", firstException); } }
private ThreadContext createThreadContext(final EntityBean entityBean) { if (entityBean == null) { throw new NullPointerException("entityBean is null"); } final BeanContext beanContext = getBeanContextByClass(entityBean.getClass()); final KeyGenerator keyGenerator = beanContext.getKeyGenerator(); final Object primaryKey = keyGenerator.getPrimaryKey(entityBean); return new ThreadContext(beanContext, primaryKey); }
public void beforeCompletion() { for (Synchronization synchronization : registry.values()) { Instance instance = synchronization.instance; // don't call beforeCompletion when transaction is marked rollback only if (txPolicy.isRollbackOnly()) return; // only call beforeCompletion on beans with session synchronization if (!synchronization.isCallSessionSynchronization()) continue; // Invoke beforeCompletion ThreadContext callContext = new ThreadContext( instance.beanContext, instance.primaryKey, Operation.BEFORE_COMPLETION); callContext.setCurrentAllowedStates(null); ThreadContext oldCallContext = ThreadContext.enter(callContext); try { instance.setInUse(true); BeanContext beanContext = instance.beanContext; List<InterceptorData> interceptors = beanContext.getCallbackInterceptors(); InterceptorStack interceptorStack = new InterceptorStack( instance.bean, null, Operation.BEFORE_COMPLETION, interceptors, instance.interceptors); interceptorStack.invoke(); instance.setInUse(false); } catch (InvalidateReferenceException e) { // exception has alredy been handled } catch (Exception e) { String message = "An unexpected system exception occured while invoking the beforeCompletion method on the SessionSynchronization object"; // [1] Log the exception or error logger.error(message, e); // [2] Mark the transaction for rollback. txPolicy.setRollbackOnly(e); // [3] Discard the instance discardInstance(callContext); // [4] throw the java.rmi.RemoteException to the client throw new RuntimeException(message, e); } finally { ThreadContext.exit(oldCallContext); } } }
public void deploy(BeanContext beanContext) throws OpenEJBException { String id = (String) beanContext.getDeploymentID(); synchronized (this) { deploymentRegistry.put(id, beanContext); beanContext.setContainer(this); } EjbTimerService timerService = beanContext.getEjbTimerService(); if (timerService != null) { timerService.start(); } }
public Instance getInstance(final ThreadContext callContext) throws OpenEJBException { final BeanContext beanContext = callContext.getBeanContext(); Data data = (Data) beanContext.getContainerData(); AtomicReference<Future<Instance>> singleton = data.singleton; try { // Has the singleton been created yet? // If there is a Future object in the AtomicReference, then // it's either been created or is being created now. Future<Instance> singletonFuture = singleton.get(); if (singletonFuture != null) return singletonFuture.get(); // The singleton has not been created nor is being created // We will construct this FutureTask and compete with the // other threads for the right to create the singleton FutureTask<Instance> task = new FutureTask<Instance>( new Callable<Instance>() { public Instance call() throws Exception { return createInstance(callContext, beanContext); } }); do { // If our FutureTask was the one to win the slot // than we are the ones responsible for creating // the singleton while the others wait. if (singleton.compareAndSet(null, task)) { task.run(); } // If we didn't win the slot and no other FutureTask // has been set by a different thread, than we need // to try again. } while ((singletonFuture = singleton.get()) == null); // At this point we can safely return the singleton return singletonFuture.get(); } catch (InterruptedException e) { Thread.interrupted(); throw new ApplicationException( new NoSuchEJBException("Singleton initialization interrupted").initCause(e)); } catch (ExecutionException e) { Throwable throwable = e.getCause(); if (throwable instanceof ApplicationException) { throw (ApplicationException) throwable; } throw new ApplicationException( new NoSuchEJBException("Singleton initialization failed").initCause(e.getCause())); } }
/** Insure that timer methods can be invoked for the current operation on this Context. */ private void checkState() throws IllegalStateException, NoSuchObjectLocalException { final BeanContext beanContext = ThreadContext.getThreadContext().getBeanContext(); final BaseContext context = (BaseContext) beanContext.get(EJBContext.class); context.check(BaseContext.Call.timerMethod); if (timerData.isCancelled()) { throw new NoSuchObjectLocalException("Timer has been cancelled"); } if (timerData.isExpired()) { throw new NoSuchObjectLocalException("The timer has expired"); } }
private Object businessMethod( final Method callMethod, final Method runMethod, 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; entrancyTracker.enter(beanContext, callContext.getPrimaryKey()); try { bean = (EntityBean) cmpEngine.loadBean(callContext, callContext.getPrimaryKey()); if (bean == null) { throw new NoSuchObjectException( beanContext.getDeploymentID() + " : " + callContext.getPrimaryKey()); } returnValue = runMethod.invoke(bean, args); // when there is not transaction, merge the data from the bean back into the cmp engine cmpEngine.storeBeanIfNoTx(callContext, bean); } catch (final NoSuchObjectException e) { handleApplicationException(txPolicy, e, false); } 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 { entrancyTracker.exit(beanContext, callContext.getPrimaryKey()); afterInvoke(txPolicy, callContext); } return returnValue; }
private void cancelTimers(final ThreadContext threadContext) { final BeanContext beanContext = threadContext.getBeanContext(); final Object primaryKey = threadContext.getPrimaryKey(); // stop timers if (primaryKey != null && beanContext.getEjbTimerService() != null) { final EjbTimerService timerService = beanContext.getEjbTimerService(); if (timerService != null && timerService instanceof EjbTimerServiceImpl) { for (final Timer timer : beanContext.getEjbTimerService().getTimers(primaryKey)) { timer.cancel(); } } } }
public void undeploy(BeanContext beanContext) { Data data = (Data) beanContext.getContainerData(); if (data == null) return; MBeanServer server = LocalMBeanServer.get(); for (ObjectName objectName : data.jmxNames) { try { server.unregisterMBean(objectName); } catch (Exception e) { logger.error("Unable to unregister MBean " + objectName); } } beanContext.setContainerData(null); }
private Instance createInstance(ThreadContext callContext, 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<InterceptorData>(), new HashMap()); ejbCreate.invoke(); } finally { callContext.setCurrentOperation(originalOperation); } } 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 java.lang.reflect.InvocationTargetException) { e = ((java.lang.reflect.InvocationTargetException) e).getTargetException(); } 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)); } }
@Override public void start(final BeanContext beanContext) throws OpenEJBException { final EjbTimerService timerService = beanContext.getEjbTimerService(); if (timerService != null) { timerService.start(); } }
private Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> createEntityManagers(BeanContext beanContext) { // create the extended entity managers Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = null; if (factories != null && factories.size() > 0) { entityManagers = new Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker>( new ArrayList<EntityManagerFactory>(factories.keySet())); for (Map.Entry<EntityManagerFactory, Map> entry : factories.entrySet()) { EntityManagerFactory entityManagerFactory = entry.getKey(); Map properties = entry.getValue(); JtaEntityManagerRegistry.EntityManagerTracker entityManagerTracker = entityManagerRegistry.getInheritedEntityManager(entityManagerFactory); EntityManager entityManager; if (entityManagerTracker == null) { if (properties != null) { entityManager = entityManagerFactory.createEntityManager(properties); } else { entityManager = entityManagerFactory.createEntityManager(); } entityManagerTracker = new JtaEntityManagerRegistry.EntityManagerTracker(entityManager); } else { entityManagerTracker.incCounter(); } entityManagers.put(entityManagerFactory, entityManagerTracker); } } return entityManagers; }
public void undeploy(BeanContext beanContext) { EjbTimerService timerService = beanContext.getEjbTimerService(); if (timerService != null) { timerService.stop(); } instanceManager.undeploy(beanContext); synchronized (this) { String id = (String) beanContext.getDeploymentID(); beanContext.setContainer(null); beanContext.setContainerData(null); deploymentRegistry.remove(id); } }
public int update( final BeanContext beanContext, final String methodSignature, final Object... args) throws FinderException { final String signature = beanContext.getAbstractSchemaName() + "." + methodSignature; // exectue the update query return cmpEngine.executeUpdateQuery(beanContext, signature, args); }
@Override public void undeploy(final BeanContext beanContext) throws OpenEJBException { synchronized (this) { deploymentsById.remove(beanContext.getDeploymentID()); beansByClass.remove(beanContext.getCmpImplClass()); try { final Field field = beanContext.getCmpImplClass().getField("deploymentInfo"); field.set(null, null); } catch (final Exception e) { // ignore } beanContext.setContainer(null); beanContext.setContainerData(null); } }
@Test public void testRollback() throws Exception { SystemInstance.init(new Properties()); final BeanContext cdi = new BeanContext( "foo", null, new ModuleContext( "foo", null, "bar", new AppContext("foo", SystemInstance.get(), null, null, null, false), null, null), Object.class, null, new HashMap<String, String>()); cdi.addApplicationException(AE1.class, true, true); cdi.addApplicationException(AE3.class, true, false); cdi.addApplicationException(AE6.class, false, true); assertEquals(ExceptionType.APPLICATION_ROLLBACK, cdi.getExceptionType(new AE1())); assertEquals(ExceptionType.APPLICATION_ROLLBACK, cdi.getExceptionType(new AE2())); assertEquals(ExceptionType.APPLICATION_ROLLBACK, cdi.getExceptionType(new AE3())); assertEquals(ExceptionType.SYSTEM, cdi.getExceptionType(new AE4())); assertEquals(ExceptionType.SYSTEM, cdi.getExceptionType(new AE5())); assertEquals(ExceptionType.APPLICATION, cdi.getExceptionType(new AE6())); assertEquals(ExceptionType.APPLICATION, cdi.getExceptionType(new AE7())); }
public StatelessContainer( Object id, SecurityService securityService, Duration accessTimeout, Duration closeTimeout, Pool.Builder poolBuilder, int callbackThreads) { this.containerID = id; this.securityService = securityService; instanceManager = new StatelessInstanceManager( securityService, accessTimeout, closeTimeout, poolBuilder, callbackThreads); for (BeanContext beanContext : deploymentRegistry.values()) { beanContext.setContainer(this); } }
private void initializeDependencies(BeanContext beanContext) throws OpenEJBException { SystemInstance systemInstance = SystemInstance.get(); ContainerSystem containerSystem = systemInstance.getComponent(ContainerSystem.class); for (String dependencyId : beanContext.getDependsOn()) { BeanContext dependencyContext = containerSystem.getBeanContext(dependencyId); if (dependencyContext == null) { throw new OpenEJBException( "Deployment does not exist. Deployment(id='" + dependencyContext + "')"); } final Object containerData = dependencyContext.getContainerData(); // Bean may not be a singleton or may be a singleton // managed by a different container implementation if (containerData instanceof Data) { Data data = (Data) containerData; data.initialize(); } } }
public synchronized void deploy(BeanContext beanContext) throws OpenEJBException { Map<Method, MethodType> methods = getLifecycleMethodsOfInterface(beanContext); deploymentsById.put(beanContext.getDeploymentID(), beanContext); beanContext.setContainer(this); Data data = new Data(new Index<Method, MethodType>(methods)); beanContext.setContainerData(data); // Create stats interceptor StatsInterceptor stats = new StatsInterceptor(beanContext.getBeanClass()); beanContext.addSystemInterceptor(stats); MBeanServer server = LocalMBeanServer.get(); ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management"); jmxName.set("J2EEServer", "openejb"); jmxName.set("J2EEApplication", null); jmxName.set("EJBModule", beanContext.getModuleID()); jmxName.set("StatelessSessionBean", beanContext.getEjbName()); jmxName.set("j2eeType", ""); jmxName.set("name", beanContext.getEjbName()); // register the invocation stats interceptor try { ObjectName objectName = jmxName.set("j2eeType", "Invocations").build(); server.registerMBean(new ManagedMBean(stats), objectName); data.jmxNames.add(objectName); } catch (Exception e) { logger.error("Unable to register MBean ", e); } try { final Context context = beanContext.getJndiEnc(); context.bind("comp/EJBContext", sessionContext); } catch (NamingException e) { throw new OpenEJBException("Failed to bind EJBContext", e); } beanContext.set(EJBContext.class, this.sessionContext); }
private void initialize(BeanContext beanContext) throws OpenEJBException { try { ThreadContext callContext = new ThreadContext(beanContext, null); ThreadContext old = ThreadContext.enter(callContext); try { getInstance(callContext); } finally { ThreadContext.exit(old); } } catch (OpenEJBException e) { throw new OpenEJBException("Singleton startup failed: " + beanContext.getDeploymentID(), e); } }