docs: @Override
      public void run() {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled())
              Tr.entry(tc, "run: " + this);
  
          EJSHome home;
          TimedObjectWrapper timedObject;
  
          try {
              // Get the currently installed and active home for this timer. It
              // is possible the home is not currently running, so an
              // EJBNotFoundException may occur.
              home = EJSContainer.getDefaultContainer().getInstalledHome(j2eeName);
  
              // Verify that the bean is still a Timer bean, in case the
              // application has been modified since the timer was created.
              if (home.beanMetaData.timedMethodInfos == null) {
                  Tr.warning(tc, "HOME_NOT_FOUND_CNTR0092W", j2eeName);
                  throw new EJBNotFoundException("Incompatible Application Change: " + j2eeName + " no longer supports timers.");
              }
          } catch (EJBNotFoundException ejbnfex) {
              FFDCFilter.processException(ejbnfex, CLASS_NAME + ".run", "305", this);
              if (isTraceOn && tc.isEntryEnabled())
                  Tr.exit(tc, "run: Failed locating timer bean " + j2eeName + " : " + ejbnfex);
              throw new TimerServiceException("Failed locating timer bean " + j2eeName, ejbnfex);
          }
  
          if (automaticMethodName != null && !validateAutomaticTimer(home.beanMetaData)) {
              // Log a message that tells the user that they will
              // need to manually remove the timers from the database.
              Tr.error(tc, "AUTOMATIC_TIMER_VALIDATION_FAILED_CNTR0301E",
                       new Object[] { j2eeName.getComponent(),
                                      j2eeName.getModule(),
                                      j2eeName.getApplication(),
                                      automaticMethodName });
              throw new EJBException("CNTR0220I: The " + j2eeName.getComponent() +
                                     " enterprise bean in the " + j2eeName.getModule() +
                                     " module of the " + j2eeName.getApplication() +
                                     " application has an automatic timer for the " + automaticMethodName +
                                     " method, but an incompatible change was made to the application since the server created the timer.");
          }
  
          // Create a Timer associated with this running Task, so it may be
          // passed on the ejbTimeout invocation. Will cache this taskHandler on the timer.
          PersistentTimer timer = createTimer(home.container.getEJBRuntime());
  
          // Get the TimedObjectWrapper from the pool to execute the method.
          timedObject = home.getTimedObjectWrapper(home.ivStatelessId); // set for singleton, stateless, and mdb
  
          // Invoke ejbTimeout on the wrapper.  No need to handle exceptions,
          // as the wrapper will have already handled/mapped any exceptions
          // as expected.
          try {
              // We are about to call the Timer's ejbTimeout method so set the Timer's instance variable which indicates this.
              timer.isTimeoutCallback = true;
  
              boolean runInGlobalTx = runInGlobalTransaction(timedObject.methodInfos[methodId]);
  
              timedObject.invokeCallback(timer, methodId, runInGlobalTx);
          } finally {
              timer.isTimeoutCallback = false;
              home.putTimedObjectWrapper(timedObject);
  
              if (isTraceOn && tc.isEntryEnabled())
                  Tr.exit(tc, "run: " + this);
          }
      }