@Override
  protected void invokePostStepArtifacts() {
    // Invoke the reducer after all parallel steps are done
    if (this.partitionReducerProxy != null) {

      try {
        if ((BatchStatus.COMPLETED).equals(stepContext.getBatchStatus())) {
          this.partitionReducerProxy.afterPartitionedStepCompletion(PartitionStatus.COMMIT);
        } else {
          this.partitionReducerProxy.afterPartitionedStepCompletion(PartitionStatus.ROLLBACK);
        }
      } catch (Exception e) {
        ExceptionConfig.wrapBatchException(e);
      }
    }

    // Called in spec'd order, e.g. Sec. 11.7
    if (stepListeners != null) {
      for (StepListener listenerProxy : stepListeners) {
        // Call afterStep on all the step listeners
        try {
          listenerProxy.afterStep();
        } catch (Exception e) {
          ExceptionConfig.wrapBatchException(e);
        }
      }
    }
  }
  @Override
  protected void invokePreStepArtifacts() {

    if (stepListeners != null) {
      for (StepListener listenerProxy : stepListeners) {
        // Call beforeStep on all the step listeners
        try {
          listenerProxy.beforeStep();
        } catch (Exception e) {
          ExceptionConfig.wrapBatchException(e);
        }
      }
    }

    // Invoke the reducer before all parallel steps start (must occur
    // before mapper as well)
    if (this.partitionReducerProxy != null) {
      try {
        this.partitionReducerProxy.beginPartitionedStep();
      } catch (Exception e) {
        ExceptionConfig.wrapBatchException(e);
      }
    }
  }