FileDocCategorySizeDatePackage
ServiceContainer.javaAPI DocJBoss 4.2.118560Fri Jul 13 20:53:50 BST 2007org.jboss.ejb3.service

ServiceContainer

public class ServiceContainer extends org.jboss.ejb3.SessionContainer implements org.jboss.ejb3.timerservice.TimedObjectInvoker
author
Kabir Khan
version
$Revision: 63290 $

Fields Summary
ServiceMBeanDelegate
delegate
Object
singleton
boolean
injected
org.jboss.ejb3.BeanContext
beanContext
MBeanServer
mbeanServer
ObjectName
delegateObjectName
private javax.ejb.TimerService
timerService
private static final Logger
log
Constructors Summary
public ServiceContainer(MBeanServer server, ClassLoader cl, String beanClassName, String ejbName, org.jboss.aop.AspectManager manager, Hashtable ctxProperties, org.jboss.ejb3.interceptor.InterceptorInfoRepository interceptorRepository, org.jboss.ejb3.Ejb3Deployment deployment)


           
                                
                            
   
      super(cl, beanClassName, ejbName, manager, ctxProperties, interceptorRepository, deployment);
      beanContextClass = ServiceBeanContext.class;
      this.mbeanServer = server;
   
Methods Summary
public voidcallTimeout(javax.ejb.Timer timer)

      Method timeout = callbackHandler.getTimeoutCallback();
      if (timeout == null) throw new EJBException("No method has been annotated with @Timeout");
      Object[] args = {timer};
      AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsFlags.IN_EJB_TIMEOUT);
      try
      {
         localInvoke(timeout, args);
      }
      catch(Throwable throwable)
      {
         if (throwable instanceof Exception) throw (Exception) throwable;
         if(throwable instanceof Error) throw (Error) throwable;
         throw new RuntimeException(throwable);
      }
      finally
      {
         AllowedOperationsAssociation.popInMethodFlag();
      }
   
public voidcreate()

      super.create();
      
      // EJBTHREE-655: fire up an instance for use as MBean delegate
      singleton = super.construct();

      // won't work, before starting the management interface MBean injection must have been done.
      //registerManagementInterface();
      
      invokeOptionalMethod("create");
   
public java.lang.ObjectcreateLocalProxy(java.lang.Object id)

      ServiceLocalProxyFactory factory = new ServiceLocalProxyFactory();
      factory.setContainer(this);

      return factory.createProxy(id);
   
public java.lang.ObjectcreateRemoteProxy(java.lang.Object id)

      ServiceRemoteProxyFactory factory = new ServiceRemoteProxyFactory();
      factory.setContainer(this);

      return factory.createProxy(id);
   
protected java.lang.ObjectcreateSession(java.lang.Class[] initTypes, java.lang.Object[] initArgs)

//      if((initTypes != null && initTypes.length > 0) || (initArgs != null && initArgs.length > 0))
//         throw new IllegalArgumentException("service bean create method must take no arguments");
      throw new RuntimeException("NYI");
   
public voiddestroy()

      invokeOptionalMethod("destroy");
      
      //unregisterManagementInterface();
      
      super.destroy();
   
public org.jboss.aop.joinpoint.InvocationResponsedynamicInvoke(java.lang.Object target, org.jboss.aop.joinpoint.Invocation invocation)

      long start = System.currentTimeMillis();
      
      ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
      EJBContainerInvocation newSi = null;
      
      MethodInvocation si = (MethodInvocation) invocation;
      MethodInfo info = (MethodInfo) methodInterceptors.get(si.getMethodHash());
      Method method = info.getUnadvisedMethod();
      try
      {
         invokeStats.callIn();
         
         Thread.currentThread().setContextClassLoader(classloader);
         
         if (info == null)
         {
            throw new RuntimeException("Could not resolve beanClass method from proxy call");
         }
         newSi = new EJBContainerInvocation(info);
         newSi.setArguments(si.getArguments());
         newSi.setMetaData(si.getMetaData());
         newSi.setAdvisor(this);

         newSi = populateInvocation(newSi);

         Object rtn = null;
         try
         {
            rtn = newSi.invokeNext();
         }
         catch (Throwable throwable)
         {
            return marshallException(invocation, throwable, newSi.getResponseContextInfo());
         }
         InvocationResponse response = SessionContainer.marshallResponse(invocation, rtn, newSi.getResponseContextInfo());

         return response;
      }
      finally
      {
         if (method != null)
         {
            long end = System.currentTimeMillis();
            long elapsed = end - start;
            invokeStats.updateStats(method, elapsed);
         }
         
         invokeStats.callOut();
         
         Thread.currentThread().setContextClassLoader(oldLoader);
      }
   
public java.lang.ObjectgetAttribute(java.lang.String attribute)

      return delegate.getAttribute(attribute);
   
public javax.management.AttributeListgetAttributes(java.lang.String[] attributes)

      return delegate.getAttributes(attributes);
   
public javax.management.MBeanInfogetMBeanInfo()

      return delegate.getMBeanInfo();
   
public java.lang.ObjectgetSingleton()

      return singleton;
   
public javax.ejb.TimerServicegetTimerService()

      return timerService;
   
public javax.ejb.TimerServicegetTimerService(java.lang.Object pKey)

      assert timerService != null : "Timer Service not yet initialized";
      return timerService;
   
protected voidinitBeanContext()

      if (beanContext == null)
      {
         synchronized(singleton)
         {
            if (beanContext == null)
            {
               try
               {
                  beanContext  = (BeanContext) beanContextClass.newInstance();
                  beanContext.setContainer(this);
                  beanContext.initialiseInterceptorInstances();
                  beanContext.setInstance(singleton);
               }
               catch (InstantiationException e)
               {
                  throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
               }
               catch (IllegalAccessException e)
               {
                  throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
               }
            }
         }
      }
   
public voidinitializePool()

      resolveInjectors();
   
protected synchronized voidinjectDependencies(org.jboss.ejb3.BeanContext ctx)

      if (injectors != null)
      {
         try
         {
            pushEnc();
            for (Injector injector : injectors)
            {
               injector.inject(ctx);
            }
         }
         finally
         {
            popEnc();
         }
      }
      injected = true;
   
public java.lang.Objectinvoke(java.lang.String actionName, java.lang.Object[] params, java.lang.String[] signature)

      return delegate.invoke(actionName, params, signature);
   
protected java.lang.ObjectinvokeEJBObjectMethod(org.jboss.ejb3.ProxyFactory factory, java.lang.Object id, org.jboss.aop.MethodInfo info, java.lang.Object[] args)

      throw new RuntimeException("NYI");
   
public voidinvokeInit(java.lang.Object bean)

      //Ignore
   
private voidinvokeOptionalMethod(java.lang.String methodName)
Invoke a method on the singleton without a specific security or transaction context.

param
methodName

      /* EJBTHREE-655 has been postponed
      ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); 
      try
      {
         Thread.currentThread().setContextClassLoader(classloader);
         Class parameterTypes[] = { };
         Method method = clazz.getMethod(methodName, parameterTypes);
         Object args[] = { };
         method.invoke(singleton, args);
      }
      catch(NoSuchMethodException e)
      {
         // ignore
      }
      catch (IllegalArgumentException e)
      {
         throw new RuntimeException(e);
      }
      catch (IllegalAccessException e)
      {
         throw new RuntimeException(e);
      }
      catch (InvocationTargetException e)
      {
         throw new RuntimeException(e.getCause());
      }
      finally
      {
         Thread.currentThread().setContextClassLoader(oldLoader);
      }
      */
   
public voidinvokePostConstruct(org.jboss.ejb3.BeanContext beanContext)

      //Ignore
   
public voidinvokePreDestroy(org.jboss.ejb3.BeanContext beanContext)

      //Ignore
   
public java.lang.ObjectlocalInvoke(java.lang.reflect.Method method, java.lang.Object[] args)
Performs a synchronous local invocation

      return localInvoke(method, args, null);
   
public java.lang.ObjectlocalInvoke(java.lang.reflect.Method method, java.lang.Object[] args, org.jboss.aspects.asynch.FutureHolder provider)
Performs a synchronous or asynchronous local invocation

param
provider If null a synchronous invocation, otherwise an asynchronous

      long start = System.currentTimeMillis();
      
      ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
      try
      {
         invokeStats.callIn();
         
         Thread.currentThread().setContextClassLoader(classloader);
         long hash = MethodHashing.calculateHash(method);
         MethodInfo info = (MethodInfo) methodInterceptors.get(hash);
         if (info == null)
         {
            throw new RuntimeException("Could not resolve beanClass method from proxy call: " + method.toString());
         }
         EJBContainerInvocation nextInvocation = new EJBContainerInvocation(info);
         nextInvocation.setAdvisor(this);
         nextInvocation.setArguments(args);

         nextInvocation = populateInvocation(nextInvocation);

         if (provider != null)
         {
            nextInvocation.getMetaData().addMetaData(AsynchronousInterceptor.ASYNCH, AsynchronousInterceptor.INVOKE_ASYNCH, "YES", PayloadKey.AS_IS);
            nextInvocation.getMetaData().addMetaData(AsynchronousInterceptor.ASYNCH, AsynchronousInterceptor.FUTURE_HOLDER, provider, PayloadKey.AS_IS);
         }
         return nextInvocation.invokeNext();
      }
      finally
      {
         if (method != null)
         {
            long end = System.currentTimeMillis();
            long elapsed = end - start;
            invokeStats.updateStats(method, elapsed);
         }
         
         invokeStats.callOut();
         
         Thread.currentThread().setContextClassLoader(oldLoader);
      }
   
protected org.jboss.ejb3.EJBContainerInvocationpopulateInvocation(org.jboss.ejb3.EJBContainerInvocation invocation)

      invocation.setTargetObject(singleton);
      invocation.setBeanContext(beanContext);
      return invocation;
   
private voidregisterManagementInterface()

      try
      {
         Management annotation = (Management)resolveAnnotation(Management.class);

         Class intf = null;
         if (annotation != null)
            intf = annotation.value();

         if (intf ==null)
         {
            Class[] interfaces = this.getBeanClass().getInterfaces();
            int interfaceIndex = 0;
            while (intf == null && interfaceIndex < interfaces.length)
            {
               if (interfaces[interfaceIndex].getAnnotation(Management.class) != null)
                  intf = interfaces[interfaceIndex];
               else
                  ++interfaceIndex;
            }
         }

         if (intf != null)
         {
            if (mbeanServer == null)
               mbeanServer = org.jboss.mx.util.MBeanServerLocator.locateJBoss();

            if (mbeanServer == null)
               throw new RuntimeException("There is a @Management interface on " + ejbName + " but the MBeanServer has not been initialized for it");

            Service service = (Service)resolveAnnotation(Service.class);

            String objname = service.objectName();
            delegateObjectName = (objname == null || objname.equals("")) ?
                            new ObjectName(getObjectName().getCanonicalName() + ",type=ManagementInterface") : new ObjectName(service.objectName());

            delegate = new ServiceMBeanDelegate(mbeanServer, this, intf, delegateObjectName);

            getDeployment().getKernelAbstraction().installMBean(delegateObjectName, getDependencyPolicy(), delegate);
         }
         else
         {
            Service service = (Service)resolveAnnotation(Service.class);
            if (service.xmbean().length() > 0)
            {
               if (mbeanServer == null)
                  mbeanServer = org.jboss.mx.util.MBeanServerLocator.locateJBoss();

               if (mbeanServer == null)
                  throw new RuntimeException(ejbName + "is defined as an XMBean, but the MBeanServer has not been initialized for it");

               String objname = service.objectName();
               delegateObjectName = (objname == null || objname.equals("")) ?
                               new ObjectName(getObjectName().getCanonicalName() + ",type=ManagementInterface") : new ObjectName(service.objectName());

               delegate = new ServiceMBeanDelegate(mbeanServer, this, service.xmbean(), delegateObjectName);

               getDeployment().getKernelAbstraction().installMBean(delegateObjectName, getDependencyPolicy(), delegate);
            }
         }
         
      }
      catch (Exception e)
      {
         throw new RuntimeException("Problem registering @Management interface for @Service " + getBeanClass(), e);
      }
   
protected voidremoveHandle(javax.ejb.Handle handle)

      throw new RuntimeException("Don't do this");
   
public voidsetAttribute(javax.management.Attribute attribute)

      delegate.setAttribute(attribute);
   
public javax.management.AttributeListsetAttributes(javax.management.AttributeList attributes)

      return delegate.setAttributes(attributes);
   
public voidstart()

      super.start();

      try
      {
         initBeanContext();

         // make sure the timer service is there before injection takes place
         timerService = TimerServiceFactory.getInstance().createTimerService(this.getObjectName(), this);

         injectDependencies(beanContext);

         // TODO: EJBTHREE-655: shouldn't happen here, but in create
         registerManagementInterface();         
        
         // only restore timers if this is a restart to avoid duplicate timers
         // when the timer is created during lifecycle
         if (timerService.getTimers().size() == 0)
            TimerServiceFactory.getInstance().restoreTimerService(timerService);
         
         invokeOptionalMethod("start");
      }
      catch (Exception e)
      {
         e.printStackTrace();
         stop();
      }
   
public voidstop()

      invokeOptionalMethod("stop");
      
      if (timerService != null)
      {
         TimerServiceFactory.getInstance().removeTimerService(timerService);
         timerService = null;
      }

      // TODO: EJBTHREE-655: shouldn't happen here, but in destroy
      unregisterManagementInterface();

      injected = false;
      
      super.stop();
   
private voidunregisterManagementInterface()

      if (delegate != null)
      {
         getDeployment().getKernelAbstraction().uninstallMBean(delegateObjectName);
      }