docs: public void validate() throws EJBConfigurationException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.entry(tc, "validate " + j2eeName);
  
          boolean asAttributesDefined = false;
  
          if (ivModuleVersion <= J2EE_EJB_VERSION_1_1) {
              // it is an EJB Module version 1.1
              // 1.a
              if (ACTIVATION_POLICY_ACTIVITY_SESSION == activationPolicy) {
                  Tr.error(tc, "INVALID_ACTIVITY_SESSION_POLICY_CNTR0069E", enterpriseBeanName);
                  throw new EJBConfigurationException("CNTR0069E: Bean \"" + enterpriseBeanName +
                                                      "\" in an EJB 1.1 module attempted to use an invalid \"Activate at\" policy of \"Activity Session\".");
  
              }
  
              // 1.b
              if (LocalTransactionSettings.BOUNDARY_ACTIVITY_SESSION == _localTran.getBoundary()) {
                  Tr.error(tc, "INVALID_ACTIVITY_SESSION_POLICY_CNTR0070E", enterpriseBeanName);
                  throw new EJBConfigurationException("CNTR0070E: Bean \"" + enterpriseBeanName +
                                                      "\" in an EJB 1.1 module attempted to use an invalid Local Transactions Boundary of \"Activity Session\".");
              }
              // 1.c
              if (LocalTransactionSettings.RESOLVER_CONTAINER_AT_BOUNDARY == _localTran.getResolver() &&
                  type != InternalConstants.TYPE_CONTAINER_MANAGED_ENTITY) { //d138543
                  Tr.error(tc, "INVALID_LOCAL_TRANSACTION_RESOLVER_CNTR0071E", enterpriseBeanName);
                  throw new EJBConfigurationException("CNTR0071E: Bean \"" + enterpriseBeanName +
                                                      "\" in an EJB 1.1 module attempted to use an invalid Local Transactions Resolution control of \"ContainerAtBoundary\".");
              }
  
          }
          if (ivModuleVersion >= J2EE_EJB_VERSION_2_0) //LI2110.41
          {
              // EJB Module version 2.x
              // 2.a if ejb2.0 module + CMAS, then only supported ActivateAt policy
              //   is Activity Session or ReadOnly
              if (isEntityBean() || isStatefulSessionBean()) {
                  // This is an Entity Bean or a Stateful Session bean
                  if (!usesBeanManagedTx) {
                      String temp_method_name = null;
  
                      // for these CMAS/TX, check if method have AS Attributes defined
                      // Need to check all methods on all interfaces....        d174057
                      EJBMethodInterface[] mtypes = EJBMethodInterface.values();
                      for (int j = 0; j < mtypes.length && !asAttributesDefined; ++j) {
                          List<EJBMethodMetaData> emi = getEJBMethodMetaData(mtypes[j]);
                          int length = 0;
                          if (emi != null) // PK31372
                          {
                              length = emi.size() - 1;
                              for (int i = 0; i < length && !asAttributesDefined; ++i) {
                                  ActivitySessionAttribute asa = ((EJBMethodInfoImpl) emi.get(i)).getActivitySessionAttribute();
                                  switch (asa.getValue()) {
                                      case ActivitySessionAttribute.BEAN_MANAGED:
                                      case ActivitySessionAttribute.REQUIRED:
                                      case ActivitySessionAttribute.SUPPORTS:
                                      case ActivitySessionAttribute.REQUIRES_NEW:
                                      case ActivitySessionAttribute.MANDATORY:
                                          temp_method_name = emi.get(i).getMethodName();
                                          asAttributesDefined = true;
                                          // FIXME: Fallthrough makes this all dead code.
                                      default:
                                          asAttributesDefined = false;
                                  }
                              } // end for (i) methodInfos
                          } // end if
                      } // end for (j) methodInterfaces
  
                      if (asAttributesDefined &&
                          ACTIVATION_POLICY_ACTIVITY_SESSION != activationPolicy &&
                          !ivReadOnlyCommitOption) // LI3408
                      {
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                              Tr.debug(tc, "Exception thrown for method " + temp_method_name);
                          Tr.error(tc, "INVALID_ACTIVITY_SESSION_POLICY_CNTR0072E",
                                   enterpriseBeanClassName);
                          throw new EJBConfigurationException("Invalid activateAt policy with Container Managed " +
                                                              "Activity Session for = " + enterpriseBeanClassName);
                      }
                  }
              }
              /*
               * //2.b if ActivateAt = AS, then loadAt must be Transaction
               * Already taken care of in method setActivationLoadPolicy. Throws CNTR0044W exception
               */
              //2.c
              if (usesBeanManagedTx) { //flags usesBeanManagedTx and usesBeanManagedAS are same. They are set if bean is BMT
                                       //It is a BMT
                                       //LTC must NOT be ContainerAtBoundary
                  if (_localTran.getResolver() == LocalTransactionSettings.RESOLVER_CONTAINER_AT_BOUNDARY) {
                      Tr.error(tc, "INVALID_LOCAL_TRANSACTION_RESOLVER_CNTR0073E", j2eeName);
                      throw new EJBConfigurationException("Unsupported Local Transaction resolution control for BeanManaged .");
                  }
              }
          } //end ejb 2.0 module if block
            // Check for invalid local transaction configuration.
            // First, check for invalid resolver configuration
            // and then check for invalid boundary.
            // 130016 and 132312 - start
          if (type == InternalConstants.TYPE_CONTAINER_MANAGED_ENTITY) { //2.d
              if (_localTran.getResolver() == LocalTransactionSettings.RESOLVER_APPLICATION) {
                  Tr.error(tc, "INVALID_CONFIGURATION_CMP_RESOLVER_APPLICATION_CNTR0065E", j2eeName);
                  throw new EJBConfigurationException("Unsupported Local Transaction resolution control for CMP Beans.");
              }
          } else if (/* type == STATELESS_SESSION || */type == InternalConstants.TYPE_MESSAGE_DRIVEN) { //2.e//d180809
              if (_localTran.getBoundary() == LocalTransactionSettings.BOUNDARY_ACTIVITY_SESSION) {
                  Tr.error(tc, "LOCAL_TRAN_BOUNDARY_ACTIVITY_INVALID_CNTR0066E", j2eeName);
                  throw new EJBConfigurationException("Local Transaction Boundary of activity session is invalid for Message Driven Beans.");
              }
          }
          //check for invalid resolver configuration 130016 and 132312- stop
  
          TransactionAttribute txAttr;
  
          // -----------------------------------------------------------------------
          // Perform EJB Specification validation for MessageDriven beans. LI2281.07
          // -----------------------------------------------------------------------
          if (type == InternalConstants.TYPE_MESSAGE_DRIVEN) {
              // MDBs may only implement some Tx Atributes...
              for (int i = 0; i < localMethodInfos.length; i++) // LIDB2110.41
              {
                  txAttr = localMethodInfos[i].getTransactionAttribute();
                  if (!(txAttr == TransactionAttribute.TX_REQUIRED ||
                        txAttr == TransactionAttribute.TX_NOT_SUPPORTED || txAttr == TransactionAttribute.TX_BEAN_MANAGED)) {
                      String method = localMethodInfos[i].getMethodName();
                      Tr.error(tc, "INVALID_TX_ATTR_CNTR0089E", // d170741
                               new Object[] { txAttr.toString(), method, j2eeName });
                      throw new EJBConfigurationException("Transaction attribute " +
                                                          txAttr.toString() + " is not allowed " +
                                                          "for method " + method + " on EJB " +
                                                          j2eeName);
                  }
              }
          }
  
          // -----------------------------------------------------------------------
          // Perform EJB Specification validation for beans that implement the
          // javax.ejb.TimedObject interface.                              LI2281.07
          // -----------------------------------------------------------------------
          if (timedMethodInfos != null) // F743-506
          {
              // Per the EJB Spec, if this bean implements the javax.ejb.TimedObject
              // interface, verify that it is a EJB 2.0 or later bean, and is not
              // a Stateful Session bean.
              if (ivModuleVersion < J2EE_EJB_VERSION_2_0 ||
                  cmpVersion == InternalConstants.CMP_VERSION_1_X ||
                  type == InternalConstants.TYPE_STATEFUL_SESSION ||
                  type == InternalConstants.TYPE_MANAGED_BEAN) {
                  Tr.error(tc, "INVALID_TIMEDOBJECT_IMPL_CNTR0088E", j2eeName); // d170741
                  throw new EJBConfigurationException("EJB 1.x, 2.0, and Stateful Session " +
                                                      "beans may not implement the " +
                                                      "javax.ejb.TimedObject interface : " +
                                                      j2eeName);
              }
  
              // F743-506 - Validate all timer methods
              for (int i = 0; i < timedMethodInfos.length; i++) {
                  // Per the Spec. TimedObject.ejbTimeout may only implement some Tx Atributes...
                  // Note:  In the 2.X specifications TX_REQUIRED was not specified as a valid
                  // transaction attribute for TimedObjects.   This did not make much sense and
                  // was changed in the 3.0 specification to allow it.   We will no longer
                  // consider this to be an error situation (even for 2.X beans).  //d366845.8
                  txAttr = timedMethodInfos[i].getTransactionAttribute();
                  if (!(txAttr == TransactionAttribute.TX_REQUIRED ||
                        txAttr == TransactionAttribute.TX_REQUIRES_NEW ||
                        txAttr == TransactionAttribute.TX_NOT_SUPPORTED || txAttr == TransactionAttribute.TX_BEAN_MANAGED)) {
                      String method = timedMethodInfos[i].getMethodName();
                      Tr.error(tc, "INVALID_TX_ATTR_CNTR0089E", // d170741
                               new Object[] { txAttr.toString(), method, j2eeName });
                      throw new EJBConfigurationException("Transaction attribute " +
                                                          txAttr.toString() + " is not allowed " +
                                                          "for method " + method + " on EJB " +
                                                          j2eeName);
                  }
              }
          }
  
          if (lifecycleInterceptorMethodInfos != null) // F743-1751
          {
              for (EJBMethodInfoImpl methodInfo : lifecycleInterceptorMethodInfos) {
                  txAttr = methodInfo.getTransactionAttribute();
                  // REQUIRED must have already been translated to REQUIRES_NEW.
                  if (txAttr != TransactionAttribute.TX_REQUIRES_NEW &&
                      txAttr != TransactionAttribute.TX_NOT_SUPPORTED &&
                      txAttr != TransactionAttribute.TX_BEAN_MANAGED) {
                      String method = methodInfo.getMethodName();
                      Tr.error(tc, "INVALID_TX_ATTR_CNTR0089E",
                               new Object[] { txAttr.toString(), method, j2eeName });
                      throw new EJBConfigurationException("Transaction attribute " +
                                                          txAttr.toString() + " is not allowed " +
                                                          "for method " + method + " on EJB " +
                                                          j2eeName);
                  }
              }
          }
  
          // ReadOnly / Interval caching option beans must be CMP 2.x or later,
          // since that is the only way to insure the state of the bean is not
          // changed/updated.                                                 LI3408
          if (ivCacheReloadType != CACHE_RELOAD_NONE) {
              if (cmpVersion < InternalConstants.CMP_VERSION_2_X) {
                  Tr.error(tc, "INVALID_CACHE_RELOAD_POLICY_CNTR0094E",
                           enterpriseBeanClassName);
  
                  StringBuffer exText = new StringBuffer();
                  exText.append("Bean ").append(j2eeName).append(" with LoadPolicy ");
                  exText.append(getCacheReloadIntervalString());
                  exText.append(" must be CMP Version 2.x or later.");
  
                  throw new EJBConfigurationException(exText.toString());
              }
          }
  
          // -----------------------------------------------------------------------
          // Perform validation for beans that implement the LightweightLocal
          // interface.                                                    LI3795-56
          // -----------------------------------------------------------------------
          if (isLightweight) {
  
              // -------------------------------------------------------------------------
              // A special check for temporary WPS hack, allowing SLSBs to be Lightweight.
              // As a performance fix for WPS, SLSBs may be Lightweight.  This is only
              // enabled by an undocumented EJB environment variable.  It cannot be
              // enabled by a WCCM config switch, nor by inheriting the Lightweight
              // interface.  The latter is flagged as an error here.  The former can
              // not happen since we do not support this in the WCCM model for SLSBs.
              //                                                                   PK21246
              // -------------------------------------------------------------------------
              if (type == InternalConstants.TYPE_STATELESS_SESSION &&
                  (LightweightLocal.class).isAssignableFrom(enterpriseBeanAbstractClass)) {
                  Tr.error(tc, "INVALID_LIGHTWEIGHT_IMPL_CNTR0119E",
                           new Object[] { j2eeName, "1" });
                  throw new EJBConfigurationException("Only Entity EJBs may implement " +
                                                      "the LightweightLocal interface : " +
                                                      j2eeName);
              }
  
              // LightweightLocal support has the following restrictions:
              //  - must be an Entity bean
              //  - must be an EJB 2.0 bean (and CMP 2.x or later)
              //  - must contain a local interface
              //  - might be a WPS hacked SLSB (ie. see above check)   PK21246
              else if (type != InternalConstants.TYPE_CONTAINER_MANAGED_ENTITY &&
                       type != InternalConstants.TYPE_BEAN_MANAGED_ENTITY &&
                       type != InternalConstants.TYPE_STATELESS_SESSION) {
                  Tr.error(tc, "INVALID_LIGHTWEIGHT_IMPL_CNTR0119E",
                           new Object[] { j2eeName, "1" });
                  throw new EJBConfigurationException("Only Entity EJBs may implement " +
                                                      "the LightweightLocal interface : " +
                                                      j2eeName);
              }
  
              if (ivModuleVersion < J2EE_EJB_VERSION_2_0 ||
                  cmpVersion == InternalConstants.CMP_VERSION_1_X) {
                  Tr.error(tc, "INVALID_LIGHTWEIGHT_IMPL_CNTR0119E",
                           new Object[] { j2eeName, "2" });
                  throw new EJBConfigurationException("EJB 1.x and CMP 1.x beans may not " +
                                                      "implement the LightweightLocal " +
                                                      "interface : " + j2eeName);
              }
  
              if (localHomeInterfaceClassName == null) {
                  Tr.error(tc, "INVALID_LIGHTWEIGHT_IMPL_CNTR0119E",
                           new Object[] { j2eeName, "3" });
                  throw new EJBConfigurationException("EJBs that implement the " +
                                                      "LightweightLocal interface must " +
                                                      "define a local interface : " + j2eeName);
              }
          }
  
          // -----------------------------------------------------------------------
          // Pre-Load Pool / Max Creation Hard Limit                      // PK20648
          // - must be a 2.0 Stateless Session bean.
          // -----------------------------------------------------------------------
          if (ivInitialPoolSize > 0 &&
              (type != InternalConstants.TYPE_STATELESS_SESSION ||
               ivModuleVersion <= J2EE_EJB_VERSION_1_1)) {
              Tr.warning(tc, "INVALID_MIN_POOLSIZE_CNTR0057W", new Object[] { j2eeName.toString(), "H" + Integer.toString(minPoolSize) });
              throw new EJBConfigurationException("A hard (H) minimum pool size may only be " +
                                                  "specified for EJB 2.x Stateless Session " +
                                                  "EJBs : " + j2eeName);
          }
          if (ivMaxCreation > 0 &&
              (type != InternalConstants.TYPE_STATELESS_SESSION ||
               ivModuleVersion <= J2EE_EJB_VERSION_1_1)) {
              Tr.warning(tc, "INVALID_MAX_POOLSIZE_CNTR0058W", new Object[] { j2eeName.toString(), "H" + Integer.toString(maxPoolSize) });
              throw new EJBConfigurationException("A hard (H) maximum pool size may only be " +
                                                  "specified for EJB 2.x Stateless Session " +
                                                  "EJBs : " + j2eeName);
          }
  
          // -----------------------------------------------------------------------
          // Option A caching and Optimistic Concurrency Control not allowed
          //                                                                116394.3
          // -----------------------------------------------------------------------
          if (optionACommitOption && optimisticConcurrencyControl) {
              Tr.warning(tc, "COMMIT_OPTION_A_AND_OPTIMISTIC_CONCURRENCY_CONTROL_NOT_SUPPORTED_CNTR0049E");
              throw new EJBConfigurationException("Using Commit Option A with Optimistic Concurrency is not supported.  EJB = " + enterpriseBeanClassName);
          }
  
          // -----------------------------------------------------------------------------------
          // Test configuration errors for beans with asynchronous methods (ie. new in EJB 3.1).                                                                 116394.3
          // -----------------------------------------------------------------------------------
  
          if (ivHasAsynchMethod) {
  
              // Asynch methods are only allowed on session beans
              if (!isSessionBean()) {
                  Tr.error(tc, "INVALID_BEAN_TYPE_FOR_ASYNCH_METHOD_CNTR0185E",
                           new Object[] { j2eeName.getComponent(), j2eeName.getModule(), j2eeName.getApplication() });
  
                  throw new EJBConfigurationException("The " + j2eeName.getComponent() + " bean in the " + j2eeName.getModule() + " module of the " +
                                                      j2eeName.getApplication() + " application has one or more asynchronous methods configured, but is not a session bean.  " +
                                                      "Asynchronous methods can only be configured on session beans.");
              }
  
          } // Validation of asynchronous methods
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
              Tr.exit(tc, "validate");
      }