FileDocCategorySizeDatePackage
EJBContainer.javaAPI DocJBoss 4.2.130259Fri Jul 13 20:53:58 BST 2007org.jboss.ejb3

EJBContainer

public abstract class EJBContainer extends org.jboss.aop.ClassContainer implements Container, org.jboss.injection.InjectionContainer
Comment
author
Bill Burke
version
$Revision: 62705 $

Fields Summary
private static final Logger
log
protected Pool
pool
protected String
ejbName
protected ObjectName
objectName
protected int
defaultConstructorIndex
protected String
beanClassName
protected ClassLoader
classloader
protected List
injectors
protected Context
enc
protected Class
beanContextClass
protected org.jboss.ejb3.interceptor.LifecycleInterceptorHandler
callbackHandler
protected Hashtable
initialContextProperties
protected Map
encInjectors
protected org.jboss.ejb3.metamodel.EnterpriseBean
xml
protected org.jboss.ejb3.metamodel.AssemblyDescriptor
assembly
protected Map
encInjections
protected org.jboss.ejb3.interceptor.InterceptorInfoRepository
interceptorRepository
protected List
classInterceptors
protected LinkedHashSet
applicableInterceptors
private HashMap
interceptorInjectors
private Ejb3Deployment
deployment
private DependencyPolicy
dependencyPolicy
private String
jaccContextId
protected HashMap
invokedMethod
protected org.jboss.ejb3.statistics.InvocationStatistics
invokeStats
private String
partitionName
public static final String
MANAGED_ENTITY_MANAGER_FACTORY
public static final String
ENTITY_MANAGER_FACTORY
Constructors Summary
public EJBContainer(String name, org.jboss.aop.AspectManager manager, ClassLoader cl, String beanClassName, String ejbName, Hashtable ctxProperties, org.jboss.ejb3.interceptor.InterceptorInfoRepository interceptorRepository, Ejb3Deployment deployment)

param
name Advisor name
param
manager Domain to get interceptor bindings from
param
cl the EJB's classloader
param
beanClassName
param
ejbName
param
ctxProperties
param
interceptorRepository
param
deployment

   
                                                                                    

         
                            
                          
   
      super(name, manager);
      this.deployment = deployment;
      this.beanClassName = beanClassName;
      this.classloader = cl;
         
      super.setChainOverridingForInheritedMethods( true );
      
      try
      {
         clazz = classloader.loadClass(beanClassName);
      }
      catch (ClassNotFoundException e)
      {
         throw new RuntimeException(e);
      }
      this.ejbName = ejbName;
      String on = Ejb3Module.BASE_EJB3_JMX_NAME + "," + getDeploymentQualifiedName();
      try
      {
         objectName = new ObjectName(on);
      }
      catch (MalformedObjectNameException e)
      {
         throw new RuntimeException("failed to create object name for: " + on, e);
      }
      initialContextProperties = ctxProperties;
      // Setting up enc the old (AS 4.2) way
      Context ctx = getInitialContext();
      try
      {
         enc = ThreadLocalENCFactory.create(ctx);
         Util.createSubcontext(enc, "env");
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);
      }
      this.interceptorRepository = interceptorRepository;
      this.interceptorRepository.addBeanClass(clazz.getName());
   
Methods Summary
public java.lang.Objectconstruct()

      Interceptor[] cInterceptors = constructorInterceptors[defaultConstructorIndex];
      if (cInterceptors == null)
      {
         try
         {
            return constructors[defaultConstructorIndex].newInstance();
         }
         catch (InstantiationException e)
         {
            throw new RuntimeException(e);
         }
         catch (IllegalAccessException e)
         {
            throw new RuntimeException(e);
         }
         catch (InvocationTargetException e)
         {
            throw new RuntimeException(e);
         }
      }
      ConstructorInvocation invocation = new ConstructorInvocation(
              cInterceptors);

      invocation.setAdvisor(this);
      invocation.setConstructor(constructors[defaultConstructorIndex]);
      try
      {
         return invocation.invokeNext();
      }
      catch (Throwable throwable)
      {
         throw new RuntimeException(throwable);
      }

   
public voidcreate()

      // EJBTHREE-655: we need an instance after create
      initializeClassContainer();
      for (int i = 0; i < constructors.length; i++)
      {
         if (constructors[i].getParameterTypes().length == 0)
         {
            defaultConstructorIndex = i;
            break;
         }
      }
   
protected voidcreateCallbackHandler()

      try
      {
         callbackHandler = new LifecycleInterceptorHandler(this,
                 getHandledCallbacks());
      }
      catch (Exception e)
      {
         throw new RuntimeException("Error creating callback handler for bean "
                 + beanClassName, e);
      }
   
public voiddestroy()

      super.cleanup();
   
protected voidfindPartitionName()

      Clustered clustered = (Clustered) resolveAnnotation(Clustered.class);
      if (clustered == null)
      {
         partitionName = null;
         return;
      }
      
      String value = clustered.partition();
      try
      {
         String replacedValue = StringPropertyReplacer.replaceProperties(value);
         if (value != replacedValue)
         {            
            log.debug("Replacing @Clustered partition attribute " + value + " with " + replacedValue);
            value = replacedValue;
         }
      }
      catch (Exception e)
      {
         log.warn("Unable to replace @Clustered partition attribute " + value + 
                  ". Caused by " + e.getClass() + " " + e.getMessage());         
      }
      
      partitionName = value;
   
public TgetAnnotation(java.lang.Class annotationType, java.lang.Class clazz)

      if (clazz == this.getBeanClass())
      {
         return (T) resolveAnnotation(annotationType);
      }
      return clazz.getAnnotation(annotationType);
   
public TgetAnnotation(java.lang.Class annotationType, java.lang.Class clazz, java.lang.reflect.Method method)

      if (clazz == this.getBeanClass())
      {
         return (T) resolveAnnotation(method, annotationType);
      }
      return method.getAnnotation(annotationType);
   
public TgetAnnotation(java.lang.Class annotationType, java.lang.reflect.Method method)

      return (T) resolveAnnotation(method, annotationType);
   
public TgetAnnotation(java.lang.Class annotationType, java.lang.Class clazz, java.lang.reflect.Field field)

      if (clazz == this.getBeanClass())
      {
         return (T) resolveAnnotation(field, annotationType);
      }
      return field.getAnnotation(annotationType);
   
public TgetAnnotation(java.lang.Class annotationType, java.lang.reflect.Field field)

      return (T) resolveAnnotation(field, annotationType);
   
public java.util.HashSetgetApplicableInterceptors()

      initialiseInterceptors();
      return applicableInterceptors;
   
public org.jboss.ejb3.metamodel.AssemblyDescriptorgetAssemblyDescriptor()

      return assembly;
   
public java.lang.ClassgetBeanClass()

      return clazz;
   
public java.lang.StringgetBeanClassName()

      return beanClassName;
   
protected java.lang.ObjectgetBridgedAnnotation(java.lang.reflect.Method bridgeMethod, java.lang.Class annotation)

      Method[] methods = bridgeMethod.getDeclaringClass().getMethods();
      int i = 0;
      boolean found = false;
      Class[] bridgeParams = bridgeMethod.getParameterTypes();
      while (i < methods.length && !found)
      {
         if (!methods[i].isBridge() && methods[i].getName().equals(bridgeMethod.getName()))
         {
            Class[] params = methods[i].getParameterTypes();
            if (params.length == bridgeParams.length)
            {
               int j = 0;
               boolean matches = true;
               while (j < params.length && matches)
               {
                  if (!bridgeParams[j].isAssignableFrom(params[j]))
                     matches = false;
                  ++j;
               }
               
               if (matches)
                  return resolveAnnotation(methods[i], annotation);
            }
         }
         ++i;
      }
 
      return null;
   
public java.lang.ObjectgetBusinessObject(BeanContext beanContext, java.lang.Class businessObject)

      throw new IllegalStateException("Not implemented");
   
public java.util.ListgetClassInterceptors()

      initialiseInterceptors();
      return classInterceptors;
   
public java.lang.ClassLoadergetClassloader()

      return classloader;
   
public DependencyPolicygetDependencyPolicy()

      return dependencyPolicy;
   
public Ejb3DeploymentgetDeployment()

      return deployment;
   
public java.lang.StringgetDeploymentDescriptorType()

      return "ejb-jar.xml";
   
public java.lang.StringgetDeploymentQualifiedName()
Returns a String identifier for this bean that is qualified by the deployment, and hence should be unique across deployments. Name is of the form "ear=foo.ear,jar=foo.jar,name=Bar", where "Bar" is the value returned by {@link #getEjbName()}. The "ear=foo.ear" portion is ommitted if the bean is not packaged in an ear.

      DeploymentScope ear = deployment.getEar();
      DeploymentUnit unit = deployment.getDeploymentUnit();
      StringBuilder sb = new StringBuilder();
      if (ear != null)
      {
         sb.append("ear=");
         sb.append(ear.getShortName());
         sb.append(",");
      }
      sb.append("jar=");
      sb.append(unit.getShortName());
      sb.append(",name=");
      sb.append(getEjbName());
      return sb.toString();
   
public DeploymentUnitgetDeploymentUnit()

      return deployment.getDeploymentUnit();
   
public java.lang.StringgetEjbJndiName(java.lang.Class businessInterface)

      return deployment.getEjbJndiName(businessInterface);
   
public java.lang.StringgetEjbJndiName(java.lang.String link, java.lang.Class businessInterface)

      return deployment.getEjbJndiName(link, businessInterface);
   
public java.lang.StringgetEjbName()

      return ejbName;
   
public javax.naming.ContextgetEnc()

//      if (enc == null)
//      {
//         enc = encFactory.getEnc(this);
//      }
      return enc;
   
public java.util.MapgetEncInjections()

      return encInjections;
   
public java.util.MapgetEncInjectors()

      return encInjectors;
   
public org.jboss.metamodel.descriptor.EnvironmentRefGroupgetEnvironmentRefGroup()

      return xml;
   
protected java.lang.Class[]getHandledCallbacks()

      return new Class[]
              {PostConstruct.class, PreDestroy.class, Timeout.class};
   
public java.lang.StringgetIdentifier()

      return getEjbName();
   
public javax.naming.InitialContextgetInitialContext()

      try
      {
         if (initialContextProperties == null)
            return new InitialContext();
         else
            return new InitialContext(initialContextProperties);
      }
      catch (NamingException e)
      {
         throw new RuntimeException(e);
      }
   
public java.util.HashtablegetInitialContextProperties()

      return initialContextProperties;
   
public java.util.ListgetInjectors()

      return injectors;
   
public java.util.HashMapgetInterceptorInjectors()

      initialiseInterceptors();
      return interceptorInjectors;
   
public org.jboss.ejb3.interceptor.InterceptorInfoRepositorygetInterceptorRepository()

      return interceptorRepository;
   
public org.jboss.ejb3.statistics.InvocationStatisticsgetInvokeStats()

      return invokeStats;
   
public java.lang.ObjectgetInvokedBusinessInterface(BeanContext beanContext)

      throw new IllegalStateException("Not implemented");
   
protected java.lang.ObjectgetInvokedInterface(java.lang.reflect.Method method)

      Remote remoteAnnotation = (Remote) resolveAnnotation(Remote.class);
      if (remoteAnnotation != null)
      {
         Class[] remotes = remoteAnnotation.value();
         for (int i = 0; i < remotes.length; ++i)
         {
            try
            {
               remotes[i].getMethod(method.getName(), method.getParameterTypes());
               return remotes[i];
            }
            catch (NoSuchMethodException e)
            {
            }
         }
      }

      Local localAnnotation = (Local) resolveAnnotation(Local.class);
      if (localAnnotation != null)
      {
         Class[] locals = localAnnotation.value();
         for (int i = 0; i < locals.length; ++i)
         {
            Method[] interfaceMethods = locals[i].getMethods();
            for (int j = 0; j < interfaceMethods.length; ++j)
            {
               if (interfaceMethods[j].equals(method))
                  return locals[i];
            }
         }
      }

      return null;
   
public java.lang.StringgetJaccContextId()

      return jaccContextId;
   
public org.jboss.aop.MethodInfogetMethodInfo(java.lang.reflect.Method method)

      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());
      }
      return info;
   
public javax.management.ObjectNamegetObjectName()

      return objectName;
   
public java.lang.StringgetPartitionName()
Gets the name of the cluster partition with which this container is associated. Not available until EJBContainer.start() is completed.

return
the name of the cluster partition with which this container is associated, or null if the container is not clustered

      return partitionName;
   
public org.jboss.ejb3.entity.PersistenceUnitDeploymentgetPersistenceUnitDeployment(java.lang.String unitName)

      return deployment.getPersistenceUnitDeployment(unitName);
   
public PoolgetPool()

      return pool;
   
public org.jboss.ejb3.metamodel.EnterpriseBeangetXml()

      return xml;
   
public booleanhasAnnotation(java.lang.Class tgt, java.lang.String annotation)

      if (annotations.hasClassAnnotation(annotation)) return true;
      if (tgt == null) return false;
      try
      {
         Class ann = loadPublicAnnotation(annotation);
         // it is metadata or CLASS annotation
         if (ann == null) return AnnotationElement.isAnyAnnotationPresent(tgt, annotation);
         return tgt.isAnnotationPresent(ann);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
      }
   
public booleanhasAnnotation(java.lang.reflect.Method m, java.lang.String annotation)

      if (annotations.hasAnnotation(m, annotation)) return true;
      try
      {
         Class ann = loadPublicAnnotation(annotation);
         // it is metadata or CLASS annotation
         if (ann == null) return AnnotationElement.isAnyAnnotationPresent(m, annotation);
         return m.isAnnotationPresent(ann);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
      }
   
public booleanhasAnnotation(java.lang.reflect.Field m, java.lang.String annotation)

      if (annotations.hasAnnotation(m, annotation)) return true;
      try
      {
         Class ann = loadPublicAnnotation(annotation);
         // it is metadata or CLASS annotation
         if (ann == null) return AnnotationElement.isAnyAnnotationPresent(m, annotation);
         return m.isAnnotationPresent(ann);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
      }
   
public booleanhasAnnotation(java.lang.reflect.Constructor m, java.lang.String annotation)

      if (annotations.hasAnnotation(m, annotation)) return true;
      try
      {
         Class ann = loadPublicAnnotation(annotation);
         // it is metadata or CLASS annotation
         if (ann == null) return AnnotationElement.isAnyAnnotationPresent(m, annotation);
         return m.isAnnotationPresent(ann);
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);  //To change body of catch statement use Options | File Templates.
      }
   
private voidinitialiseInterceptors()

      if (applicableInterceptors == null)
      {
         log.debug("Initialising interceptors for " + getEjbName() + "...");
         HashSet<InterceptorInfo> defaultInterceptors = interceptorRepository.getDefaultInterceptors();
         log.debug("Default interceptors: " + defaultInterceptors);

         classInterceptors = interceptorRepository.getClassInterceptors(this);
         log.debug("Class interceptors: " + classInterceptors);

         applicableInterceptors = new LinkedHashSet<InterceptorInfo>();
         if (defaultInterceptors != null) applicableInterceptors.addAll(defaultInterceptors);
         if (classInterceptors != null) applicableInterceptors.addAll(classInterceptors);

         Method[] methods = clazz.getMethods();
         for (int i = 0; i < methods.length; i++)
         {
            List methodIcptrs = interceptorRepository.getMethodInterceptors(this, methods[i]);
            if (methodIcptrs != null && methodIcptrs.size() > 0)
            {
               log.debug("Method interceptors for  " + methods[i] + ": " + methodIcptrs);
               applicableInterceptors.addAll(methodIcptrs);
            }
         }
         log.debug("All applicable interceptor classes: " + applicableInterceptors);
      }
   
protected voidinitializePool()

      PoolClass poolClass = (PoolClass) resolveAnnotation(PoolClass.class);
      Class<? extends Pool> poolClazz = poolClass.value();
      int maxSize = poolClass.maxSize();
      long timeout = poolClass.timeout();
      pool = poolClazz.newInstance();
      pool.initialize(this, beanContextClass, clazz, maxSize, timeout);

      resolveInjectors();
      pool.setInjectors(injectors.toArray(new Injector[injectors.size()]));
   
public voidinstantiated()
EJBContainer has finished with all metadata initialization from XML files and such. this is really a hook to do some processing after XML has been set up and before and processing of dependencies and such.


   
public voidinvokeInit(java.lang.Object bean)


   
public voidinvokeInit(java.lang.Object bean, java.lang.Class[] initParameterTypes, java.lang.Object[] initParameterValues)


   
public voidinvokePostActivate(BeanContext beanContext)

      throw new RuntimeException("PostActivate not implemented for container");
   
public voidinvokePostConstruct(BeanContext beanContext)

      callbackHandler.postConstruct(beanContext);
   
public voidinvokePreDestroy(BeanContext beanContext)

      callbackHandler.preDestroy(beanContext);
   
public voidinvokePrePassivate(BeanContext beanContext)

      throw new RuntimeException("PrePassivate not implemented for container");
   
private java.lang.ClassloadPublicAnnotation(java.lang.String annotation)

      try
      {
         Class ann = classloader.loadClass(annotation);
         if (!ann.isAnnotation()) return null;
         Retention retention = (Retention) ann.getAnnotation(Retention.class);
         if (retention != null && retention.value() == RetentionPolicy.RUNTIME) return ann;

      }
      catch (ClassNotFoundException ignored)
      {
      }
      return null;
   
public voidpopEnc()
Pops EJB's ENC from the stack. Delegates to whatever implementation is used to pop the EJB's ENC from the stock

      ThreadLocalENCFactory.pop();
//      encFactory.popEnc(this);
   
public voidprocessMetadata(DependencyPolicy dependencyPolicy)
introspects EJB container to find all dependencies and initialize any extra metadata.

This must be called before container is registered with any microcontainer

param
dependencyPolicy

      this.dependencyPolicy = dependencyPolicy;
      // XML must be done first so that any annotation overrides are initialized

      // todo injection handlers should be pluggable from XML
      Collection<InjectionHandler> handlers = new ArrayList<InjectionHandler>();
      handlers.add(new EJBHandler());
      handlers.add(new DependsHandler());
      handlers.add(new JndiInjectHandler());
      handlers.add(new PersistenceContextHandler());
      handlers.add(new PersistenceUnitHandler());
      handlers.add(new ResourceHandler());
      handlers.add(new WebServiceRefHandler());

      ClassLoader old = Thread.currentThread().getContextClassLoader();
      Thread.currentThread().setContextClassLoader(classloader);
      try
      {
         // EJB container's XML must be processed before interceptor's as it may override interceptor's references
         for (InjectionHandler handler : handlers) handler.loadXml(xml, this);

         Map<AccessibleObject, Injector> tmp = InjectionUtil.processAnnotations(this, handlers, getBeanClass());
         injectors.addAll(tmp.values());

         initialiseInterceptors();
         for (InterceptorInfo interceptorInfo : applicableInterceptors)
         {
            for (InjectionHandler handler : handlers)
            {
               handler.loadXml(interceptorInfo.getXml(), this);
            }
         }
         for (InterceptorInfo interceptorInfo : applicableInterceptors)
         {
            Map<AccessibleObject, Injector> tmpInterceptor = InjectionUtil.processAnnotations(this, handlers, interceptorInfo.getClazz());
            InterceptorInjector injector = new InterceptorInjector(this, interceptorInfo, tmpInterceptor);
            interceptorInjectors.put(interceptorInfo.getClazz(), injector);
         }
      }
      finally
      {
         Thread.currentThread().setContextClassLoader(old);
      }
   
public voidpushEnc()
Makes sure that EJB's ENC is available Delegates to whatever implementation is used to push the ENC of the EJB onto the stack

      ThreadLocalENCFactory.push(enc);
//      encFactory.pushEnc(this);
   
public java.lang.ObjectresolveAnnotation(java.lang.reflect.Method m, java.lang.Class annotation)

      Object value = super.resolveAnnotation(m, annotation);
      if (value == null && m.isBridge()) value = getBridgedAnnotation(m, annotation);
      return value;
   
public java.lang.ObjectresolveAnnotation(java.lang.reflect.Method m, java.lang.Class[] annotationChoices)

      Object value = null;
      int i = 0;
      while (value == null && i < annotationChoices.length){
         value = resolveAnnotation(m, annotationChoices[i++]);
      }
      
      return value;
   
public ContainerresolveEjbContainer(java.lang.String link, java.lang.Class businessIntf)

      return deployment.getEjbContainer(link, businessIntf);
   
public ContainerresolveEjbContainer(java.lang.Class businessIntf)

      return deployment.getEjbContainer(businessIntf);
   
protected voidresolveInjectors()


       
   
      pushEnc();
      try
      {
         Thread.currentThread().setContextClassLoader(classloader);
         try
         {
            Util.rebind(getEnc(), "UserTransaction", new UserTransactionImpl());
         }
         catch (NamingException e)
         {
            NamingException namingException = new NamingException("Could not bind user transaction for ejb name " + ejbName + " into JNDI under jndiName: " + getEnc().getNameInNamespace() + "/" + "UserTransaction");
            namingException.setRootCause(e);
            throw namingException;
         }
      }
      finally
      {
         popEnc();
      }
   
public voidsetAssemblyDescriptor(org.jboss.ejb3.metamodel.AssemblyDescriptor assembly)

      this.assembly = assembly;
   
public voidsetJaccContextId(java.lang.String jaccContextId)

      this.jaccContextId = jaccContextId;
   
public voidsetXml(org.jboss.ejb3.metamodel.EnterpriseBean xml)

      this.xml = xml;
   
public voidstart()

      initializePool();

      for (EncInjector injector : encInjectors.values())
      {
         injector.inject(this);   
      }

      // creating of injector array should come after injection into ENC as an ENC injector
      // may add additional injectors into the injector list.  An example is an extended persistence
      // context which mush be created and added to the SFSB bean context.

      Injector[] injectors2 = injectors.toArray(new Injector[injectors.size()]);
      if (pool != null) pool.setInjectors(injectors2);

      createCallbackHandler();

      JaccHelper.configureContainer(jaccContextId, this);
      
      // If we're clustered, find our partition name
      findPartitionName();
      
      log.info("STARTED EJB: " + clazz.getName() + " ejbName: " + ejbName);
   
public voidstop()

//      encFactory.cleanupEnc(this);
      
      if (pool != null)
      {
         pool.destroy();
         pool = null;
      }
      
      log.info("STOPPED EJB: " + clazz.getName() + " ejbName: " + ejbName);