code: @SuppressWarnings("deprecation")
    private void jobCompleteUnprotected() {
      //
      // All tasks are complete, then the job is done!
      
      if(this.terminated == JobStatus.FAILED 
          || this.terminated == JobStatus.KILLED) {
        terminate(this.terminated);
      }
      if (this.status.getRunState() == JobStatus.RUNNING ||
          this.status.getRunState() == JobStatus.PREP) {
        changeStateTo(JobStatus.SUCCEEDED);
        this.status.setCleanupProgress(1.0f);
        if (maps.length == 0) {
          this.status.setMapProgress(1.0f);
        }
        if (reduces.length == 0) {
          this.status.setReduceProgress(1.0f);
        }
        this.finishTime = clock.getTime();
        LOG.info("Job " + this.status.getJobID() +
                 " has completed successfully.");
  
        // Log the job summary (this should be done prior to logging to
        // job-history to ensure job-counters are in-sync
        JobSummary.logJobSummary(this);
  
        Counters counters = getCounters();
        // Log job-history
        jobHistory.logFinished(finishTime,
                               this.finishedMapTasks,
                               this.finishedReduceTasks, failedMapTasks,
                               failedReduceTasks, killedMapTasks,
                               killedReduceTasks, getMapCounters(),
                               getReduceCounters(), counters);
      }
    }
docs: The job is done since all it's component tasks are either
  successful or have failed.