@SuppressWarnings("unchecked")
  protected void recoverApplication(ApplicationState appState, RMState rmState) throws Exception {
    ApplicationSubmissionContext appContext = appState.getApplicationSubmissionContext();
    ApplicationId appId = appState.getAppId();

    // create and recover app.
    RMAppImpl application =
        createAndPopulateNewRMApp(appContext, appState.getSubmitTime(), appState.getUser());
    application.recover(rmState);
    if (isApplicationInFinalState(appState.getState())) {
      // We are synchronously moving the application into final state so that
      // momentarily client will not see this application in NEW state. Also
      // for finished applications we will avoid renewing tokens.
      application.handle(new RMAppEvent(appId, RMAppEventType.RECOVER));
      return;
    }

    if (UserGroupInformation.isSecurityEnabled()) {
      Credentials credentials = null;
      try {
        credentials = parseCredentials(appContext);
        // synchronously renew delegation token on recovery.
        rmContext
            .getDelegationTokenRenewer()
            .addApplicationSync(appId, credentials, appContext.getCancelTokensWhenComplete());
        application.handle(new RMAppEvent(appId, RMAppEventType.RECOVER));
      } catch (Exception e) {
        LOG.warn("Unable to parse and renew delegation tokens.", e);
        this.rmContext
            .getDispatcher()
            .getEventHandler()
            .handle(new RMAppRejectedEvent(appId, e.getMessage()));
        throw e;
      }
    } else {
      application.handle(new RMAppEvent(appId, RMAppEventType.RECOVER));
    }
  }