@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);
        }
    }
@ Override public void run ( ) { final boolean isTraceOn = TraceComponent . isAnyTracingEnabled ( ) ; if ( isTraceOn && tc . isEntryEnabled ( ) ) Tr . entry ( tc , "run: " + this ) ; EJSHome home ; TimedObjectWrapper timedObject ; try { home = EJSContainer . getDefaultContainer ( ) . getInstalledHome ( j2eeName ) ; 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 ) ) { 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." ) ; } PersistentTimer timer = createTimer ( home . container . getEJBRuntime ( ) ) ; timedObject = home . getTimedObjectWrapper ( home . ivStatelessId ) ; try { 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 ) ; } }
Performs the work associated with the scheduled task / EJB timer. <p>

When the EJB timer expires, this method will be called. A wrapper for the
target timer bean will be obtained, and the timeout method will be invoked. <p>

The wrapper is similar to a generated Local wrapper, and will activate the
bean as needed. It will also perform exception handling / mapping as
required by the EJB Specification.