This is an automated email from the ASF dual-hosted git repository.

steveloughran pushed a commit to branch branch-3.5
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/branch-3.5 by this push:
     new bc15cd3e0cf MAPREDUCE-6706. TaskUmbilicalProtocol to use 
ProtobufRPCEngine2 (#8422) (#8574)
bc15cd3e0cf is described below

commit bc15cd3e0cfd64532e0ad2edc3b7d285e3e6fdd2
Author: Steve Loughran <[email protected]>
AuthorDate: Tue Jun 30 09:47:23 2026 +0100

    MAPREDUCE-6706. TaskUmbilicalProtocol to use ProtobufRPCEngine2 (#8422) 
(#8574)
    
    
    This moves the TaskUmbilicalProtocol between Mappers, Reducers and the
    MRAppMaster to using ProtobufRPCEngine2
    
    Contains code written by Github Copilot
    
    Contributed by Steve Loughran
---
 .../hadoop-mapreduce-client-app/pom.xml            |  31 ++
 .../hadoop/mapred/LocalContainerLauncher.java      |  72 +++--
 .../hadoop/mapred/TaskAttemptListenerImpl.java     | 107 ++++---
 .../java/org/apache/hadoop/mapred/YarnChild.java   |  43 +--
 .../mapred/protocolPB/TaskUmbilicalProtocolPB.java |  39 +++
 .../TaskUmbilicalProtocolPBClientImpl.java         | 337 +++++++++++++++++++++
 ...askUmbilicalProtocolServerSideTranslatorPB.java | 322 ++++++++++++++++++++
 .../protocolPB/TaskUmbilicalProtocolUtils.java     | 190 ++++++++++++
 .../hadoop/mapred/protocolPB/package-info.java}    |  51 +---
 .../app/security/authorize/MRAMPolicyProvider.java |   4 +-
 .../src/main/proto/TaskUmbilicalProtocol.proto     | 187 ++++++++++++
 .../java/org/apache/hadoop/mapred/JvmContext.java  |   6 +-
 .../org/apache/hadoop/mapred/SortedRanges.java     |   6 +-
 .../java/org/apache/hadoop/mapred/TaskStatus.java  |  46 ++-
 .../TestUmbilicalProtocolWithJobToken.java         |  48 +--
 15 files changed, 1321 insertions(+), 168 deletions(-)

diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/pom.xml
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/pom.xml
index ed611676968..f4c0d70a01d 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/pom.xml
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/pom.xml
@@ -192,6 +192,37 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.xolstice.maven.plugins</groupId>
+        <artifactId>protobuf-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>src-compile-protoc</id>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>com.google.code.maven-replacer-plugin</groupId>
+        <artifactId>replacer</artifactId>
+        <executions>
+          <execution>
+            <id>replace-generated-sources</id>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          
<excludePackageNames>org.apache.hadoop.mapred.proto</excludePackageNames>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/LocalContainerLauncher.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/LocalContainerLauncher.java
index 1548bcc3c6b..11dc9461fff 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/LocalContainerLauncher.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/LocalContainerLauncher.java
@@ -93,7 +93,7 @@ public class LocalContainerLauncher extends AbstractService 
implements
   private Thread eventHandler;
   private byte[] encryptedSpillKey = new byte[] {0};
   private BlockingQueue<ContainerLauncherEvent> eventQueue =
-      new LinkedBlockingQueue<ContainerLauncherEvent>();
+      new LinkedBlockingQueue<>();
 
   public LocalContainerLauncher(AppContext context,
                                 TaskUmbilicalProtocol umbilical) {
@@ -115,8 +115,8 @@ public LocalContainerLauncher(AppContext context,
     try {
       curFC = FileContext.getFileContext(curDir.toURI());
     } catch (UnsupportedFileSystemException ufse) {
-      LOG.error("Local filesystem " + curDir.toURI().toString()
-                + " is unsupported?? (should never happen)");
+      LOG.error("Local filesystem {} is unsupported?? (should never happen)",
+          curDir.toURI());
     }
 
     // Save list of files/dirs that are supposed to be present so can delete
@@ -126,10 +126,8 @@ public LocalContainerLauncher(AppContext context,
     // uberization in order to run correctly).
     File[] curLocalFiles = curDir.listFiles();
     if (curLocalFiles != null) {
-      HashSet<File> lf = new HashSet<File>(curLocalFiles.length);
-      for (int j = 0; j < curLocalFiles.length; ++j) {
-        lf.add(curLocalFiles[j]);
-      }
+      HashSet<File> lf = new HashSet<>(curLocalFiles.length);
+      Collections.addAll(lf, curLocalFiles);
       localizedFiles = Collections.unmodifiableSet(lf);
     }
 
@@ -157,26 +155,29 @@ public void serviceStart() throws Exception {
     // thread context classloader so that it can be used by the event handler
     // as well as the subtask runner threads
     if (jobClassLoader != null) {
-      LOG.info("Setting " + jobClassLoader +
-          " as the context classloader of thread " + eventHandler.getName());
+      LOG.info("Setting {} as the context classloader of thread {}", 
jobClassLoader,
+          eventHandler.getName());
       eventHandler.setContextClassLoader(jobClassLoader);
     } else {
       // note the current TCCL
-      LOG.info("Context classloader of thread " + eventHandler.getName() +
-          ": " + eventHandler.getContextClassLoader());
+      LOG.info("Context classloader of thread {}: {}", eventHandler.getName(),
+          eventHandler.getContextClassLoader());
     }
     eventHandler.start();
     super.serviceStart();
   }
 
   public void serviceStop() throws Exception {
-    if (eventHandler != null) {
-      eventHandler.interrupt();
-    }
-    if (taskRunner != null) {
-      taskRunner.shutdownNow();
+    try {
+      if (eventHandler != null) {
+        eventHandler.interrupt();
+      }
+      if (taskRunner != null) {
+        taskRunner.shutdownNow();
+      }
+    } finally {
+      super.serviceStop();
     }
-    super.serviceStop();
   }
 
   @Override
@@ -223,7 +224,7 @@ private class EventHandler implements Runnable {
     private int finishedSubMaps = 0;
 
     private final Map<TaskAttemptId,Future<?>> futures =
-        new ConcurrentHashMap<TaskAttemptId,Future<?>>();
+        new ConcurrentHashMap<>();
 
     EventHandler() {
     }
@@ -235,7 +236,7 @@ public void run() {
 
       // Collect locations of map outputs to give to reduces
       final Map<TaskAttemptID, MapOutputFile> localMapFiles =
-          new HashMap<TaskAttemptID, MapOutputFile>();
+          new HashMap<>();
       
       // _must_ either run subtasks sequentially or accept expense of new JVMs
       // (i.e., fork()), else will get weird failures when maps try to create/
@@ -244,11 +245,11 @@ public void run() {
         try {
           event = eventQueue.take();
         } catch (InterruptedException e) {  // mostly via T_KILL? JOB_KILL?
-          LOG.warn("Returning, interrupted : " + e);
+          LOG.warn("Returning, interrupted : {}", String.valueOf(e));
           break;
         }
 
-        LOG.info("Processing the event " + event.toString());
+        LOG.info("Processing the event {}", event);
 
         if (event.getType() == EventType.CONTAINER_REMOTE_LAUNCH) {
 
@@ -295,7 +296,7 @@ public void run() {
           TaskAttemptId taId = event.getTaskAttemptID();
           Future<?> future = futures.remove(taId);
           if (future != null) {
-            LOG.info("canceling the task attempt " + taId);
+            LOG.info("canceling the task attempt {}", taId);
             future.cancel(true);
           }
 
@@ -378,14 +379,12 @@ private void runTask(ContainerRemoteLaunchEvent launchEv,
         // if umbilical itself barfs (in error-handler of runSubMap()),
         // we're pretty much hosed, so do what YarnChild main() does
         // (i.e., exit clumsily--but can never happen, so no worries!)
-        LOG.error("oopsie...  this can never happen: "
-            + StringUtils.stringifyException(ioe));
+        LOG.error("oopsie...  this can never happen: {}", 
StringUtils.stringifyException(ioe));
         ExitUtil.terminate(-1);
       } finally {
         // remove my future
         if (futures.remove(attemptID) != null) {
-          LOG.info("removed attempt " + attemptID +
-              " from the futures to keep track of");
+          LOG.info("removed attempt {} from the futures to keep track of", 
attemptID);
         }
       }
     }
@@ -460,8 +459,8 @@ private void runSubtask(org.apache.hadoop.mapred.Task task,
             // checking event queue is a tad wacky...but could enforce ordering
             // (assuming no "lost events") at LocalMRAppMaster [CURRENT 
BUG(?): 
             // doesn't send reduce event until maps all done]
-            LOG.error("CONTAINER_REMOTE_LAUNCH contains a reduce task ("
-                      + attemptID + "), but not yet finished with maps");
+            LOG.error("CONTAINER_REMOTE_LAUNCH contains a reduce task ({}),"
+                + " but not yet finished with maps", attemptID);
             throw new RuntimeException();
           }
 
@@ -487,16 +486,15 @@ private void runSubtask(org.apache.hadoop.mapred.Task 
task,
         throw new RuntimeException();
 
       } catch (Exception exception) {
-        LOG.warn("Exception running local (uberized) 'child' : "
-            + StringUtils.stringifyException(exception));
+        LOG.warn("Exception running local (uberized) 'child' : {}",
+            StringUtils.stringifyException(exception));
         try {
           if (task != null) {
             // do cleanup for the task
             task.taskCleanup(umbilical);
           }
         } catch (Exception e) {
-          LOG.info("Exception cleaning up: "
-              + StringUtils.stringifyException(e));
+          LOG.info("Exception cleaning up: {}", 
StringUtils.stringifyException(e));
         }
         // Report back any failures, for diagnostic purposes
         umbilical.reportDiagnosticInfo(classicAttemptID, 
@@ -543,9 +541,8 @@ private void relocalize() {
               deleted = false;
             }
             if (!deleted) {
-              LOG.warn("Unable to delete unexpected local file/dir "
-                  + curLocalFiles[j].getName()
-                  + ": insufficient permissions?");
+              LOG.warn("Unable to delete unexpected local file/dir {}: 
insufficient permissions?",
+                  curLocalFiles[j].getName());
             }
           }
         }
@@ -576,9 +573,8 @@ protected static MapOutputFile 
renameMapOutputForReduce(JobConf conf,
     Path mapOutIndex = subMapOutputFile.getOutputIndexFile();
     Path reduceInIndex = new Path(reduceIn.toString() + ".index");
     if (LOG.isDebugEnabled()) {
-      LOG.debug("Renaming map output file for task attempt "
-          + mapId.toString() + " from original location " + mapOut.toString()
-          + " to destination " + reduceIn.toString());
+      LOG.debug("Renaming map output file for task attempt {} from original 
location {}"
+              + " to destination {}", mapId, mapOut, reduceIn);
     }
     if (!localFs.mkdirs(reduceIn.getParent())) {
       throw new IOException("Mkdirs failed to create "
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/TaskAttemptListenerImpl.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/TaskAttemptListenerImpl.java
index 5dffd735fda..f0bd4f4ff04 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/TaskAttemptListenerImpl.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/TaskAttemptListenerImpl.java
@@ -34,9 +34,13 @@
 import org.apache.hadoop.classification.VisibleForTesting;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
+import org.apache.hadoop.ipc.ProtobufRpcEngine2;
 import org.apache.hadoop.ipc.ProtocolSignature;
 import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.ipc.Server;
+import org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPB;
+import 
org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolServerSideTranslatorPB;
 import org.apache.hadoop.mapred.SortedRanges.Range;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.TypeConverter;
@@ -62,12 +66,13 @@
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.security.authorize.PolicyProvider;
 import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.thirdparty.protobuf.BlockingService;
 import org.apache.hadoop.util.StringInterner;
 import org.apache.hadoop.util.Time;
 import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
 
 /**
- * This class is responsible for talking to the task umblical.
+ * This class is responsible for talking to the task umbilical.
  * It also converts all the old data structures
  * to yarn data structures.
  * 
@@ -82,32 +87,32 @@ public class TaskAttemptListenerImpl extends 
CompositeService
   private static final Logger LOG =
       LoggerFactory.getLogger(TaskAttemptListenerImpl.class);
 
-  private AppContext context;
+  private final AppContext context;
   private Server server;
   protected TaskHeartbeatHandler taskHeartbeatHandler;
-  private RMHeartbeatHandler rmHeartbeatHandler;
+  private final RMHeartbeatHandler rmHeartbeatHandler;
   private long commitWindowMs;
   private InetSocketAddress address;
-  private ConcurrentMap<WrappedJvmID, org.apache.hadoop.mapred.Task>
+  private final ConcurrentMap<WrappedJvmID, org.apache.hadoop.mapred.Task>
     jvmIDToActiveAttemptMap
-      = new ConcurrentHashMap<WrappedJvmID, org.apache.hadoop.mapred.Task>();
+      = new ConcurrentHashMap<>();
 
-  private ConcurrentMap<TaskAttemptId,
+  private final ConcurrentMap<TaskAttemptId,
       AtomicReference<TaskAttemptStatus>> attemptIdToStatus
         = new ConcurrentHashMap<>();
 
   /**
    * A Map to keep track of the history of logging each task attempt.
    */
-  private ConcurrentHashMap<TaskAttemptID, TaskProgressLogPair>
+  private final ConcurrentHashMap<TaskAttemptID, TaskProgressLogPair>
       taskAttemptLogProgressStamps = new ConcurrentHashMap<>();
 
-  private Set<WrappedJvmID> launchedJVMs = Collections
-      .newSetFromMap(new ConcurrentHashMap<WrappedJvmID, Boolean>());
+  private final Set<WrappedJvmID> launchedJVMs = Collections
+      .newSetFromMap(new ConcurrentHashMap<>());
 
   private JobTokenSecretManager jobTokenSecretManager = null;
-  private AMPreemptionPolicy preemptionPolicy;
-  private byte[] encryptedSpillKey;
+  private final AMPreemptionPolicy preemptionPolicy;
+  private final byte[] encryptedSpillKey;
 
   public TaskAttemptListenerImpl(AppContext context,
       JobTokenSecretManager jobTokenSecretManager,
@@ -155,11 +160,19 @@ protected void registerHeartbeatHandler(Configuration 
conf) {
   protected void startRpcServer() {
     Configuration conf = getConfig();
     try {
-      server = new RPC.Builder(conf).setProtocol(TaskUmbilicalProtocol.class)
-          .setInstance(this).setBindAddress("0.0.0.0")
+      RPC.setProtocolEngine(conf, TaskUmbilicalProtocolPB.class,
+          ProtobufRpcEngine2.class);
+      TaskUmbilicalProtocolServerSideTranslatorPB translator =
+          new TaskUmbilicalProtocolServerSideTranslatorPB(this);
+      BlockingService blockingService =
+          TaskUmbilicalProtocolProtos.TaskUmbilicalProtocolService
+              .newReflectiveBlockingService(translator);
+      server = new RPC.Builder(conf)
+          .setProtocol(TaskUmbilicalProtocolPB.class)
+          .setInstance(blockingService)
+          .setBindAddress("0.0.0.0")
           .setPortRangeConfig(MRJobConfig.MR_AM_JOB_CLIENT_PORT_RANGE)
-          .setNumHandlers(
-          conf.getInt(MRJobConfig.MR_AM_TASK_LISTENER_THREAD_COUNT, 
+          
.setNumHandlers(conf.getInt(MRJobConfig.MR_AM_TASK_LISTENER_THREAD_COUNT,
           MRJobConfig.DEFAULT_MR_AM_TASK_LISTENER_THREAD_COUNT))
           .setVerbose(false).setSecretManager(jobTokenSecretManager).build();
 
@@ -186,8 +199,11 @@ void refreshServiceAcls(Configuration configuration,
 
   @Override
   protected void serviceStop() throws Exception {
-    stopRpcServer();
-    super.serviceStop();
+    try {
+      stopRpcServer();
+    } finally {
+      super.serviceStop();
+    }
   }
 
   protected void stopRpcServer() {
@@ -213,7 +229,7 @@ public InetSocketAddress getAddress() {
    */
   @Override
   public boolean canCommit(TaskAttemptID taskAttemptID) throws IOException {
-    LOG.info("Commit go/no-go request from " + taskAttemptID.toString());
+    LOG.info("Commit go/no-go request from {}", taskAttemptID.toString());
     // An attempt is asking if it can commit its output. This can be decided
     // only by the task which is managing the multiple attempts. So redirect 
the
     // request there.
@@ -248,7 +264,7 @@ public boolean canCommit(TaskAttemptID taskAttemptID) 
throws IOException {
   @Override
   public void commitPending(TaskAttemptID taskAttemptID, TaskStatus taskStatsu)
           throws IOException, InterruptedException {
-    LOG.info("Commit-pending state update from " + taskAttemptID.toString());
+    LOG.info("Commit-pending state update from {}", taskAttemptID.toString());
     // An attempt is asking if it can commit its output. This can be decided
     // only by the task which is managing the multiple attempts. So redirect 
the
     // request there.
@@ -265,7 +281,7 @@ public void commitPending(TaskAttemptID taskAttemptID, 
TaskStatus taskStatsu)
   @Override
   public void preempted(TaskAttemptID taskAttemptID, TaskStatus taskStatus)
           throws IOException, InterruptedException {
-    LOG.info("Preempted state update from " + taskAttemptID.toString());
+    LOG.info("Preempted state update from {}", taskAttemptID.toString());
     // An attempt is telling us that it got preempted.
     org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId attemptID =
         TypeConverter.toYarn(taskAttemptID);
@@ -280,7 +296,7 @@ public void preempted(TaskAttemptID taskAttemptID, 
TaskStatus taskStatus)
 
   @Override
   public void done(TaskAttemptID taskAttemptID) throws IOException {
-    LOG.info("Done acknowledgment from " + taskAttemptID.toString());
+    LOG.info("Done acknowledgment from {}", taskAttemptID.toString());
 
     org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId attemptID =
         TypeConverter.toYarn(taskAttemptID);
@@ -295,7 +311,7 @@ public void done(TaskAttemptID taskAttemptID) throws 
IOException {
   public void fatalError(TaskAttemptID taskAttemptID, String msg, boolean 
fastFail)
       throws IOException {
     // This happens only in Child and in the Task.
-    LOG.error("Task: " + taskAttemptID + " - exited : " + msg);
+    LOG.error("Task: {} - exited : {}", taskAttemptID, msg);
     reportDiagnosticInfo(taskAttemptID, "Error: " + msg);
 
     org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId attemptID =
@@ -312,8 +328,7 @@ public void fatalError(TaskAttemptID taskAttemptID, String 
msg, boolean fastFail
   public void fsError(TaskAttemptID taskAttemptID, String message)
       throws IOException {
     // This happens only in Child.
-    LOG.error("Task: " + taskAttemptID + " - failed due to FSError: "
-        + message);
+    LOG.error("Task: {} - failed due to FSError: {}", taskAttemptID, message);
     reportDiagnosticInfo(taskAttemptID, "FSError: " + message);
 
     org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId attemptID =
@@ -335,8 +350,8 @@ public void shuffleError(TaskAttemptID taskAttemptID, 
String message) throws IOE
   public MapTaskCompletionEventsUpdate getMapCompletionEvents(
       JobID jobIdentifier, int startIndex, int maxEvents,
       TaskAttemptID taskAttemptID) throws IOException {
-    LOG.info("MapCompletionEvents request from " + taskAttemptID.toString()
-        + ". startIndex " + startIndex + " maxEvents " + maxEvents);
+    LOG.info("MapCompletionEvents request from {}. startIndex {} maxEvents {}",
+        taskAttemptID.toString(), startIndex, maxEvents);
 
     // TODO: shouldReset is never used. See TT. Ask for Removal.
     boolean shouldReset = false;
@@ -355,8 +370,7 @@ public MapTaskCompletionEventsUpdate getMapCompletionEvents(
   public void reportDiagnosticInfo(TaskAttemptID taskAttemptID, String 
diagnosticInfo)
  throws IOException {
     diagnosticInfo = StringInterner.weakIntern(diagnosticInfo);
-    LOG.info("Diagnostics report from " + taskAttemptID.toString() + ": "
-        + diagnosticInfo);
+    LOG.info("Diagnostics report from {}: {}", taskAttemptID.toString(), 
diagnosticInfo);
 
     org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId attemptID =
       TypeConverter.toYarn(taskAttemptID);
@@ -389,8 +403,7 @@ public AMFeedback statusUpdate(TaskAttemptID taskAttemptID,
       // down gracefully or receiving a thread dump signal. Tolerate unknown
       // tasks as long as they have unregistered recently.
       if (!taskHeartbeatHandler.hasRecentlyUnregistered(yarnAttemptID)) {
-        LOG.error("Status update was called with illegal TaskAttemptId: "
-            + yarnAttemptID);
+        LOG.error("Status update was called with illegal TaskAttemptId: {}", 
yarnAttemptID);
         feedback.setTaskFound(false);
       }
       return feedback;
@@ -400,14 +413,14 @@ public AMFeedback statusUpdate(TaskAttemptID 
taskAttemptID,
     if (getConfig().getBoolean(MRJobConfig.TASK_PREEMPTION, false)
         && preemptionPolicy.isPreempted(yarnAttemptID)) {
       feedback.setPreemption(true);
-      LOG.info("Setting preemption bit for task: "+ yarnAttemptID
-          + " of type " + yarnAttemptID.getTaskId().getTaskType());
+      LOG.info("Setting preemption bit for task: {} of type {}", yarnAttemptID,
+          yarnAttemptID.getTaskId().getTaskType());
     }
 
     if (taskStatus == null) {
       //We are using statusUpdate only as a simple ping
       if (LOG.isDebugEnabled()) {
-        LOG.debug("Ping from " + taskAttemptID.toString());
+        LOG.debug("Ping from {}", taskAttemptID.toString());
       }
       // Consider ping from the tasks for liveliness check
       if 
(getConfig().getBoolean(MRJobConfig.MR_TASK_ENABLE_PING_FOR_LIVELINESS_CHECK,
@@ -459,9 +472,9 @@ public AMFeedback statusUpdate(TaskAttemptID taskAttemptID,
     
     //set the fetch failures
     if (taskStatus.getFetchFailedMaps() != null 
-        && taskStatus.getFetchFailedMaps().size() > 0) {
-      taskAttemptStatus.fetchFailedMaps = 
-        new 
ArrayList<org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId>();
+        && !taskStatus.getFetchFailedMaps().isEmpty()) {
+      taskAttemptStatus.fetchFailedMaps =
+          new ArrayList<>();
       for (TaskAttemptID failedMapId : taskStatus.getFetchFailedMaps()) {
         taskAttemptStatus.fetchFailedMaps.add(
             TypeConverter.toYarn(failedMapId));
@@ -505,7 +518,7 @@ public JvmTask getTask(JvmContext context) throws 
IOException {
     // A rough imitation of code from TaskTracker.
 
     JVMId jvmId = context.jvmId;
-    LOG.info("JVM with ID : " + jvmId + " asked for a task");
+    LOG.info("JVM with ID : {} asked for a task", jvmId);
 
     JvmTask jvmTask = null;
     // TODO: Is it an authorized container to get a task? Otherwise return 
null.
@@ -519,13 +532,13 @@ public JvmTask getTask(JvmContext context) throws 
IOException {
     // Try to look up the task. We remove it directly as we don't give
     // multiple tasks to a JVM
     if (!jvmIDToActiveAttemptMap.containsKey(wJvmID)) {
-      LOG.info("JVM with ID: " + jvmId + " is invalid and will be killed.");
+      LOG.info("JVM with ID: {} is invalid and will be killed.", jvmId);
       jvmTask = TASK_FOR_INVALID_JVM;
     } else {
       if (!launchedJVMs.contains(wJvmID)) {
         jvmTask = null;
-        LOG.info("JVM with ID: " + jvmId
-            + " asking for task before AM launch registered. Given null task");
+        LOG.info("JVM with ID: {} asking for task before AM launch registered. 
Given null task",
+            jvmId);
       } else {
         // remove the task as it is no more needed and free up the memory.
         // Also we have already told the JVM to process a task, so it is no
@@ -533,7 +546,7 @@ public JvmTask getTask(JvmContext context) throws 
IOException {
         org.apache.hadoop.mapred.Task task =
             jvmIDToActiveAttemptMap.remove(wJvmID);
         launchedJVMs.remove(wJvmID);
-        LOG.info("JVM with ID: " + jvmId + " given task: " + task.getTaskID());
+        LOG.info("JVM with ID: {} given task: {}", jvmId, task.getTaskID());
         task.setEncryptedSpillKey(encryptedSpillKey);
         jvmTask = new JvmTask(task, false);
       }
@@ -594,7 +607,7 @@ public ProtocolSignature getProtocolSignature(String 
protocol,
         protocol, clientVersion, clientMethodsHash);
   }
 
-  // task checkpoint bookeeping
+  // task checkpoint bookkeeping
   @Override
   public TaskCheckpointID getCheckpointID(TaskID taskId) {
     TaskId tid = TypeConverter.toYarn(taskId);
@@ -634,8 +647,8 @@ private void coalesceStatusUpdate(TaskAttemptId 
yarnAttemptID,
       // it processes the update, or by another IPC server handler
       done = lastStatusRef.compareAndSet(lastStatus, taskAttemptStatus);
       if (!done) {
-        LOG.info("TaskAttempt " + yarnAttemptID +
-            ": lastStatusRef changed by another thread, retrying...");
+        LOG.info("TaskAttempt {}: lastStatusRef changed by another thread, 
retrying...",
+            yarnAttemptID);
         // let's revert taskAttemptStatus.fetchFailedMaps
         taskAttemptStatus.fetchFailedMaps = fetchFailedMaps;
       }
@@ -687,12 +700,10 @@ private void resetLog(final boolean doLog,
       if (doLog) {
         prevProgress = processedProgress;
         logTimeStamp = timestamp;
-        LOG.info("Progress of TaskAttempt " + taskAttemptID + " is : "
-            + progress);
+        LOG.info("Progress of TaskAttempt {} is : {}", taskAttemptID, 
progress);
       } else {
         if (LOG.isDebugEnabled()) {
-          LOG.debug("Progress of TaskAttempt " + taskAttemptID + " is : "
-              + progress);
+          LOG.debug("Progress of TaskAttempt {} is : {}", taskAttemptID, 
progress);
         }
       }
     }
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/YarnChild.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/YarnChild.java
index bbf527ebff5..ab5e241262b 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/YarnChild.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/YarnChild.java
@@ -19,7 +19,9 @@
 package org.apache.hadoop.mapred;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.apache.hadoop.io.IOUtils.closeStream;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
@@ -35,7 +37,10 @@
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.ipc.CallerContext;
+import org.apache.hadoop.ipc.ProtobufRpcEngine2;
 import org.apache.hadoop.ipc.RPC;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPB;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPBClientImpl;
 import org.apache.hadoop.mapreduce.MRConfig;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.TaskType;
@@ -116,9 +121,14 @@ public static void main(String[] args) throws Throwable {
       taskOwner.doAs(new PrivilegedExceptionAction<TaskUmbilicalProtocol>() {
       @Override
       public TaskUmbilicalProtocol run() throws Exception {
-        return (TaskUmbilicalProtocol)RPC.getProxy(TaskUmbilicalProtocol.class,
-            TaskUmbilicalProtocol.versionID, address, job);
-      }
+          RPC.setProtocolEngine(job, TaskUmbilicalProtocolPB.class,
+              ProtobufRpcEngine2.class);
+          TaskUmbilicalProtocolPB proxy = RPC.getProxy(
+              TaskUmbilicalProtocolPB.class,
+              RPC.getProtocolVersion(TaskUmbilicalProtocolPB.class),
+              address, job);
+          return new TaskUmbilicalProtocolPBClientImpl(proxy);
+        }
     });
 
     // report non-pid to application master
@@ -185,8 +195,7 @@ public Object run() throws Exception {
         umbilical.fsError(taskid, e.getMessage());
       }
     } catch (Exception exception) {
-      LOG.warn("Exception running child : "
-          + StringUtils.stringifyException(exception));
+      LOG.warn("Exception running child : {}", 
StringUtils.stringifyException(exception));
       try {
         if (task != null) {
           // do cleanup for the task
@@ -194,17 +203,14 @@ public Object run() throws Exception {
             task.taskCleanup(umbilical);
           } else {
             final Task taskFinal = task;
-            childUGI.doAs(new PrivilegedExceptionAction<Object>() {
-              @Override
-              public Object run() throws Exception {
-                taskFinal.taskCleanup(umbilical);
-                return null;
-              }
+            childUGI.doAs((PrivilegedExceptionAction<Object>) () -> {
+              taskFinal.taskCleanup(umbilical);
+              return null;
             });
           }
         }
       } catch (Exception e) {
-        LOG.info("Exception cleaning up: " + 
StringUtils.stringifyException(e));
+        LOG.info("Exception cleaning up: {}", 
StringUtils.stringifyException(e));
       }
       // Report back any failures, for diagnostic purposes
       if (taskid != null) {
@@ -213,8 +219,7 @@ public Object run() throws Exception {
         }
       }
     } catch (Throwable throwable) {
-      LOG.error("Error running child : "
-               + StringUtils.stringifyException(throwable));
+      LOG.error("Error running child : {}", 
StringUtils.stringifyException(throwable));
       if (taskid != null) {
         if (!ShutdownHookManager.get().isShutdownInProgress()) {
           Throwable tCause = throwable.getCause();
@@ -225,7 +230,11 @@ public Object run() throws Exception {
         }
       }
     } finally {
-      RPC.stopProxy(umbilical);
+      if (umbilical instanceof Closeable closeable) {
+        closeStream(closeable);
+      } else {
+        RPC.stopProxy(umbilical);
+      }
       DefaultMetricsSystem.shutdown();
       TaskLog.syncLogsShutdown(logSyncer);
     }
@@ -278,7 +287,7 @@ private static void configureLocalDirs(Task task, JobConf 
job) throws IOExceptio
     String[] localSysDirs = StringUtils.getTrimmedStrings(
         System.getenv(Environment.LOCAL_DIRS.name()));
     job.setStrings(MRConfig.LOCAL_DIR, localSysDirs);
-    LOG.info(MRConfig.LOCAL_DIR + " for child: " + 
job.get(MRConfig.LOCAL_DIR));
+    LOG.info(MRConfig.LOCAL_DIR + " for child: {}", 
job.get(MRConfig.LOCAL_DIR));
     LocalDirAllocator lDirAlloc = new LocalDirAllocator(MRConfig.LOCAL_DIR);
     Path workDir = null;
     // First, try to find the JOB_LOCAL_DIR on this host.
@@ -318,7 +327,7 @@ private static void configureTask(JobConf job, Task task,
     ApplicationAttemptId appAttemptId = ContainerId.fromString(
         System.getenv(Environment.CONTAINER_ID.name()))
         .getApplicationAttemptId();
-    LOG.debug("APPLICATION_ATTEMPT_ID: " + appAttemptId);
+    LOG.debug("APPLICATION_ATTEMPT_ID: {}", appAttemptId);
     // Set it in conf, so as to be able to be used the the OutputCommitter.
     job.setInt(MRJobConfig.APPLICATION_ATTEMPT_ID,
         appAttemptId.getAttemptId());
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPB.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPB.java
new file mode 100644
index 00000000000..c3814cb9b01
--- /dev/null
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPB.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.mapred.protocolPB;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.ipc.ProtocolInfo;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.TaskUmbilicalProtocolService;
+import org.apache.hadoop.mapreduce.security.token.JobTokenSelector;
+import org.apache.hadoop.security.token.TokenInfo;
+
+/**
+ * Protocol buffer based RPC interface for {@link 
org.apache.hadoop.mapred.TaskUmbilicalProtocol}.
+ * Protocol version 1 corresponds to the TaskUmbilicalProtocol.versionID used 
in
+ * the Writable-based RPC implementation.
+ */
[email protected]
+@ProtocolInfo(
+    protocolName = "org.apache.hadoop.mapred.TaskUmbilicalProtocol",
+    protocolVersion = 1)
+@TokenInfo(JobTokenSelector.class)
+public interface TaskUmbilicalProtocolPB
+    extends TaskUmbilicalProtocolService.BlockingInterface {
+}
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPBClientImpl.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPBClientImpl.java
new file mode 100644
index 00000000000..bc9fb0c1be0
--- /dev/null
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolPBClientImpl.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.mapred.protocolPB;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.ipc.ProtocolSignature;
+import org.apache.hadoop.ipc.RPC;
+import org.apache.hadoop.mapred.AMFeedback;
+import org.apache.hadoop.mapred.JobID;
+import org.apache.hadoop.mapred.JvmContext;
+import org.apache.hadoop.mapred.JvmTask;
+import org.apache.hadoop.mapred.MapTaskCompletionEventsUpdate;
+import org.apache.hadoop.mapred.SortedRanges;
+import org.apache.hadoop.mapred.TaskAttemptID;
+import org.apache.hadoop.mapred.TaskID;
+import org.apache.hadoop.mapred.TaskStatus;
+import org.apache.hadoop.mapred.TaskUmbilicalProtocol;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CanCommitRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CommitPendingRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.DoneRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FatalErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FsErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetCheckpointIDRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetCheckpointIDResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetMapCompletionEventsRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetMapCompletionEventsResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetTaskRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetTaskResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.PreemptedRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportDiagnosticInfoRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportNextRecordRangeRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.SetCheckpointIDRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ShuffleErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.StatusUpdateRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.StatusUpdateResponseProto;
+import org.apache.hadoop.mapreduce.checkpoint.TaskCheckpointID;
+
+import static org.apache.hadoop.ipc.RPC.stopProxy;
+import static 
org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolUtils.service;
+
+/**
+ * Client-side translator to translate calls from {@link TaskUmbilicalProtocol}
+ * to the RPC server implementing {@link TaskUmbilicalProtocolPB}.
+ */
[email protected]
+public class TaskUmbilicalProtocolPBClientImpl
+    implements TaskUmbilicalProtocol, Closeable {
+
+  private final TaskUmbilicalProtocolPB proxy;
+
+  public TaskUmbilicalProtocolPBClientImpl(TaskUmbilicalProtocolPB proxy) {
+    this.proxy = proxy;
+  }
+
+  @Override
+  public void close() throws IOException {
+    stopProxy(proxy);
+  }
+
+  @Override
+  public long getProtocolVersion(String protocol, long clientVersion)
+      throws IOException {
+    return RPC.getProtocolVersion(TaskUmbilicalProtocolPB.class);
+  }
+
+  @Override
+  public ProtocolSignature getProtocolSignature(
+      String protocol, long clientVersion, int clientMethodsHash)
+      throws IOException {
+    return ProtocolSignature.getProtocolSignature(this,
+        protocol, clientVersion, clientMethodsHash);
+  }
+
+  @Override
+  public JvmTask getTask(JvmContext context) throws IOException {
+    return service(() -> {
+      GetTaskRequestProto.Builder builder = GetTaskRequestProto.newBuilder();
+      if (context != null) {
+        builder.setJvmContext(
+            TaskUmbilicalProtocolUtils.serialize(context));
+      }
+      GetTaskResponseProto response =
+          proxy.getTask(null, builder.build());
+      if (!response.hasJvmTask()) {
+        return null;
+      }
+      return TaskUmbilicalProtocolUtils.deserialize(
+          new JvmTask(), response.getJvmTask());
+    });
+  }
+
+  @Override
+  public AMFeedback statusUpdate(TaskAttemptID taskId, TaskStatus taskStatus)
+      throws IOException, InterruptedException {
+    return service(() -> {
+      StatusUpdateRequestProto.Builder builder =
+          StatusUpdateRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      if (taskStatus != null) {
+        builder.setTaskStatus(
+            TaskUmbilicalProtocolUtils.serializeTaskStatus(
+                taskStatus));
+      }
+      StatusUpdateResponseProto response =
+          proxy.statusUpdate(null, builder.build());
+      AMFeedback feedback = new AMFeedback();
+      feedback.setTaskFound(response.getTaskFound());
+      feedback.setPreemption(response.getPreemption());
+      return feedback;
+    });
+  }
+
+  @Override
+  public void reportDiagnosticInfo(TaskAttemptID taskid, String trace)
+      throws IOException {
+    service(() -> {
+      ReportDiagnosticInfoRequestProto.Builder builder =
+          ReportDiagnosticInfoRequestProto.newBuilder();
+      if (taskid != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskid));
+      }
+      builder.setTrace(trace != null ? trace : "");
+      proxy.reportDiagnosticInfo(null, builder.build());
+    });
+  }
+
+  @Override
+  public void reportNextRecordRange(TaskAttemptID taskid,
+      SortedRanges.Range range) throws IOException {
+    service(() -> {
+      ReportNextRecordRangeRequestProto.Builder builder =
+          ReportNextRecordRangeRequestProto.newBuilder();
+      if (taskid != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskid));
+      }
+      if (range != null) {
+        builder.setRange(
+            TaskUmbilicalProtocolUtils.serialize(range));
+      }
+      proxy.reportNextRecordRange(null, builder.build());
+    });
+  }
+
+  @Override
+  public void done(TaskAttemptID taskid) throws IOException {
+    service(() -> {
+      DoneRequestProto.Builder builder = DoneRequestProto.newBuilder();
+      if (taskid != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskid));
+      }
+      proxy.done(null, builder.build());
+    });
+  }
+
+  @Override
+  public void commitPending(TaskAttemptID taskId, TaskStatus taskStatus)
+      throws IOException, InterruptedException {
+    service(() -> {
+      CommitPendingRequestProto.Builder builder =
+          CommitPendingRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      if (taskStatus != null) {
+        builder.setTaskStatus(
+            TaskUmbilicalProtocolUtils.serializeTaskStatus(
+                taskStatus));
+      }
+      proxy.commitPending(null, builder.build());
+    });
+  }
+
+  @Override
+  public boolean canCommit(TaskAttemptID taskid) throws IOException {
+    return service(() -> {
+      CanCommitRequestProto.Builder builder =
+          CanCommitRequestProto.newBuilder();
+      if (taskid != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskid));
+      }
+      return proxy.canCommit(null, builder.build()).getCanCommit();
+    });
+  }
+
+  @Override
+  public void shuffleError(TaskAttemptID taskId, String message)
+      throws IOException {
+    service(() -> {
+      ShuffleErrorRequestProto.Builder builder =
+          ShuffleErrorRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      builder.setMessage(message != null ? message : "");
+      proxy.shuffleError(null, builder.build());
+    });
+  }
+
+  @Override
+  public void fsError(TaskAttemptID taskId, String message) throws IOException 
{
+    service(() -> {
+      FsErrorRequestProto.Builder builder = FsErrorRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      builder.setMessage(message != null ? message : "");
+      proxy.fsError(null, builder.build());
+    });
+  }
+
+  @Override
+  public void fatalError(TaskAttemptID taskId, String msg, boolean fastFail)
+      throws IOException {
+    service(() -> {
+      FatalErrorRequestProto.Builder builder =
+          FatalErrorRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      builder.setMessage(msg != null ? msg : "");
+      builder.setFastFail(fastFail);
+      proxy.fatalError(null, builder.build());
+    });
+  }
+
+  @Override
+  public MapTaskCompletionEventsUpdate getMapCompletionEvents(JobID jobId,
+      int fromIndex, int maxLocs, TaskAttemptID id) throws IOException {
+    return service(() -> {
+      GetMapCompletionEventsRequestProto.Builder builder =
+          GetMapCompletionEventsRequestProto.newBuilder();
+      if (jobId != null) {
+        builder.setJobId(
+            TaskUmbilicalProtocolUtils.serialize(jobId));
+      }
+      builder.setFromIndex(fromIndex);
+      builder.setMaxLocs(maxLocs);
+      if (id != null) {
+        builder.setTaskAttemptId(
+            TaskUmbilicalProtocolUtils.serialize(id));
+      }
+      GetMapCompletionEventsResponseProto response =
+          proxy.getMapCompletionEvents(null, builder.build());
+      if (!response.hasEventsUpdate()) {
+        return null;
+      }
+      return TaskUmbilicalProtocolUtils.deserialize(
+          new MapTaskCompletionEventsUpdate(), response.getEventsUpdate());
+    });
+  }
+
+  @Override
+  public void preempted(TaskAttemptID taskId, TaskStatus taskStatus)
+      throws IOException, InterruptedException {
+    service(() -> {
+      PreemptedRequestProto.Builder builder = 
PreemptedRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      if (taskStatus != null) {
+        builder.setTaskStatus(
+            TaskUmbilicalProtocolUtils.serializeTaskStatus(
+                taskStatus));
+      }
+      proxy.preempted(null, builder.build());
+    });
+  }
+
+  @Override
+  public TaskCheckpointID getCheckpointID(TaskID taskId) {
+    return service(() -> {
+      GetCheckpointIDRequestProto.Builder builder =
+          GetCheckpointIDRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      GetCheckpointIDResponseProto response =
+          proxy.getCheckpointID(null, builder.build());
+      if (!response.hasCheckpointId()) {
+        return null;
+      }
+      return TaskUmbilicalProtocolUtils.deserialize(
+          new TaskCheckpointID(), response.getCheckpointId());
+    });
+  }
+
+  @Override
+  public void setCheckpointID(TaskID taskId, TaskCheckpointID checkpointId) {
+    service(() -> {
+      SetCheckpointIDRequestProto.Builder builder =
+          SetCheckpointIDRequestProto.newBuilder();
+      if (taskId != null) {
+        builder.setTaskId(
+            TaskUmbilicalProtocolUtils.serialize(taskId));
+      }
+      if (checkpointId != null) {
+        builder.setCheckpointId(
+            TaskUmbilicalProtocolUtils.serialize(checkpointId));
+      }
+      proxy.setCheckpointID(null, builder.build());
+    });
+  }
+
+
+}
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolServerSideTranslatorPB.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolServerSideTranslatorPB.java
new file mode 100644
index 00000000000..f31a4aa1eb5
--- /dev/null
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolServerSideTranslatorPB.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.mapred.protocolPB;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.mapred.AMFeedback;
+import org.apache.hadoop.mapred.JobID;
+import org.apache.hadoop.mapred.JvmContext;
+import org.apache.hadoop.mapred.JvmTask;
+import org.apache.hadoop.mapred.MapTaskCompletionEventsUpdate;
+import org.apache.hadoop.mapred.SortedRanges;
+import org.apache.hadoop.mapred.TaskAttemptID;
+import org.apache.hadoop.mapred.TaskID;
+import org.apache.hadoop.mapred.TaskStatus;
+import org.apache.hadoop.mapred.TaskUmbilicalProtocol;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CanCommitRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CanCommitResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CommitPendingRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.CommitPendingResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.DoneRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.DoneResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FatalErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FatalErrorResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FsErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.FsErrorResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetCheckpointIDRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetCheckpointIDResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetMapCompletionEventsRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetMapCompletionEventsResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetTaskRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.GetTaskResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.PreemptedRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.PreemptedResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportDiagnosticInfoRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportDiagnosticInfoResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportNextRecordRangeRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ReportNextRecordRangeResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.SetCheckpointIDRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.SetCheckpointIDResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ShuffleErrorRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.ShuffleErrorResponseProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.StatusUpdateRequestProto;
+import 
org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos.StatusUpdateResponseProto;
+import org.apache.hadoop.mapreduce.checkpoint.TaskCheckpointID;
+import org.apache.hadoop.thirdparty.protobuf.RpcController;
+import org.apache.hadoop.thirdparty.protobuf.ServiceException;
+
+import static 
org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolUtils.translate;
+
+/**
+ * Server-side translator to translate the requests received on
+ * {@link TaskUmbilicalProtocolPB} to the calls in {@link 
TaskUmbilicalProtocol}.
+ */
[email protected]
+public class TaskUmbilicalProtocolServerSideTranslatorPB
+    implements TaskUmbilicalProtocolPB {
+
+  private static final ReportDiagnosticInfoResponseProto 
VOID_REPORT_DIAG_RESPONSE =
+      ReportDiagnosticInfoResponseProto.newBuilder().build();
+
+  private static final ReportNextRecordRangeResponseProto 
VOID_REPORT_RANGE_RESPONSE =
+      ReportNextRecordRangeResponseProto.newBuilder().build();
+
+  private static final DoneResponseProto VOID_DONE_RESPONSE =
+      DoneResponseProto.newBuilder().build();
+
+  private static final CommitPendingResponseProto VOID_COMMIT_PENDING_RESPONSE 
=
+      CommitPendingResponseProto.newBuilder().build();
+
+  private static final ShuffleErrorResponseProto VOID_SHUFFLE_ERROR_RESPONSE =
+      ShuffleErrorResponseProto.newBuilder().build();
+
+  private static final FsErrorResponseProto VOID_FS_ERROR_RESPONSE =
+      FsErrorResponseProto.newBuilder().build();
+
+  private static final FatalErrorResponseProto VOID_FATAL_ERROR_RESPONSE =
+      FatalErrorResponseProto.newBuilder().build();
+
+  private static final PreemptedResponseProto VOID_PREEMPTED_RESPONSE =
+      PreemptedResponseProto.newBuilder().build();
+
+  private static final SetCheckpointIDResponseProto 
VOID_SET_CHECKPOINT_RESPONSE =
+      SetCheckpointIDResponseProto.newBuilder().build();
+
+
+  private final TaskUmbilicalProtocol impl;
+
+  public TaskUmbilicalProtocolServerSideTranslatorPB(TaskUmbilicalProtocol 
impl) {
+    this.impl = impl;
+  }
+
+  @Override
+  public GetTaskResponseProto getTask(RpcController controller,
+      GetTaskRequestProto request) throws ServiceException {
+    return translate(() -> {
+      JvmContext context = request.hasJvmContext()
+          ? TaskUmbilicalProtocolUtils.deserialize(new JvmContext(), 
request.getJvmContext())
+          : null;
+      JvmTask task = impl.getTask(context);
+      GetTaskResponseProto.Builder builder = GetTaskResponseProto.newBuilder();
+      if (task != null) {
+        builder.setJvmTask(TaskUmbilicalProtocolUtils.serialize(task));
+      }
+      return builder.build();
+    });
+  }
+
+  @Override
+  public StatusUpdateResponseProto statusUpdate(RpcController controller,
+      StatusUpdateRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      TaskStatus taskStatus = null;
+      if (request.hasTaskStatus()) {
+        taskStatus = 
TaskUmbilicalProtocolUtils.deserializeTaskStatus(request.getTaskStatus());
+      }
+      AMFeedback feedback = impl.statusUpdate(taskId, taskStatus);
+      return StatusUpdateResponseProto.newBuilder()
+          .setTaskFound(feedback.getTaskFound())
+          .setPreemption(feedback.getPreemption())
+          .build();
+    });
+  }
+
+  @Override
+  public ReportDiagnosticInfoResponseProto reportDiagnosticInfo(
+      RpcController controller,
+      ReportDiagnosticInfoRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      impl.reportDiagnosticInfo(taskId, request.getTrace());
+      return VOID_REPORT_DIAG_RESPONSE;
+    });
+  }
+
+  @Override
+  public ReportNextRecordRangeResponseProto reportNextRecordRange(
+      RpcController controller,
+      ReportNextRecordRangeRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      SortedRanges.Range range = request.hasRange()
+          ? TaskUmbilicalProtocolUtils.deserialize(new SortedRanges.Range(), 
request.getRange())
+          : null;
+      impl.reportNextRecordRange(taskId, range);
+      return VOID_REPORT_RANGE_RESPONSE;
+    });
+  }
+
+  @Override
+  public DoneResponseProto done(RpcController controller,
+      DoneRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      impl.done(taskId);
+      return VOID_DONE_RESPONSE;
+    });
+  }
+
+  @Override
+  public CommitPendingResponseProto commitPending(RpcController controller,
+      CommitPendingRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      TaskStatus taskStatus = null;
+      if (request.hasTaskStatus()) {
+        taskStatus = 
TaskUmbilicalProtocolUtils.deserializeTaskStatus(request.getTaskStatus());
+      }
+      impl.commitPending(taskId, taskStatus);
+      return VOID_COMMIT_PENDING_RESPONSE;
+    });
+  }
+
+  @Override
+  public CanCommitResponseProto canCommit(RpcController controller,
+      CanCommitRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      boolean canCommit = impl.canCommit(taskId);
+      return CanCommitResponseProto.newBuilder()
+          .setCanCommit(canCommit)
+          .build();
+    });
+  }
+
+  @Override
+  public ShuffleErrorResponseProto shuffleError(RpcController controller,
+      ShuffleErrorRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      impl.shuffleError(taskId, request.getMessage());
+      return VOID_SHUFFLE_ERROR_RESPONSE;
+    });
+  }
+
+  @Override
+  public FsErrorResponseProto fsError(RpcController controller,
+      FsErrorRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      impl.fsError(taskId, request.getMessage());
+      return VOID_FS_ERROR_RESPONSE;
+    });
+  }
+
+  @Override
+  public FatalErrorResponseProto fatalError(RpcController controller,
+      FatalErrorRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      impl.fatalError(taskId, request.getMessage(), request.getFastFail());
+      return VOID_FATAL_ERROR_RESPONSE;
+    });
+  }
+
+  @Override
+  public GetMapCompletionEventsResponseProto getMapCompletionEvents(
+      RpcController controller,
+      GetMapCompletionEventsRequestProto request) throws ServiceException {
+    return translate(() -> {
+      JobID jobId = request.hasJobId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new JobID(), 
request.getJobId())
+          : null;
+      TaskAttemptID taskAttemptId = request.hasTaskAttemptId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskAttemptId())
+          : null;
+      MapTaskCompletionEventsUpdate update = impl.getMapCompletionEvents(
+          jobId, request.getFromIndex(), request.getMaxLocs(), taskAttemptId);
+      GetMapCompletionEventsResponseProto.Builder builder =
+          GetMapCompletionEventsResponseProto.newBuilder();
+      if (update != null) {
+        builder.setEventsUpdate(TaskUmbilicalProtocolUtils.serialize(update));
+      }
+      return builder.build();
+    });
+  }
+
+  @Override
+  public PreemptedResponseProto preempted(RpcController controller,
+      PreemptedRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskAttemptID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskAttemptID(), 
request.getTaskId())
+          : null;
+      TaskStatus taskStatus = null;
+      if (request.hasTaskStatus()) {
+        taskStatus = 
TaskUmbilicalProtocolUtils.deserializeTaskStatus(request.getTaskStatus());
+      }
+      impl.preempted(taskId, taskStatus);
+      return VOID_PREEMPTED_RESPONSE;
+    });
+  }
+
+  @Override
+  public GetCheckpointIDResponseProto getCheckpointID(RpcController controller,
+      GetCheckpointIDRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskID(), 
request.getTaskId())
+          : null;
+      TaskCheckpointID checkpointID = impl.getCheckpointID(taskId);
+      GetCheckpointIDResponseProto.Builder builder =
+          GetCheckpointIDResponseProto.newBuilder();
+      if (checkpointID != null) {
+        
builder.setCheckpointId(TaskUmbilicalProtocolUtils.serialize(checkpointID));
+      }
+      return builder.build();
+    });
+  }
+
+  @Override
+  public SetCheckpointIDResponseProto setCheckpointID(RpcController controller,
+      SetCheckpointIDRequestProto request) throws ServiceException {
+    return translate(() -> {
+      TaskID taskId = request.hasTaskId()
+          ? TaskUmbilicalProtocolUtils.deserialize(new TaskID(), 
request.getTaskId())
+          : null;
+      TaskCheckpointID checkpointID = null;
+      if (request.hasCheckpointId()) {
+        checkpointID = TaskUmbilicalProtocolUtils.deserialize(new 
TaskCheckpointID(),
+            request.getCheckpointId());
+      }
+      impl.setCheckpointID(taskId, checkpointID);
+      return VOID_SET_CHECKPOINT_RESPONSE;
+    });
+  }
+
+}
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolUtils.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolUtils.java
new file mode 100644
index 00000000000..9ed7d5d42ef
--- /dev/null
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/TaskUmbilicalProtocolUtils.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.mapred.protocolPB;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+
+import org.apache.hadoop.io.DataInputBuffer;
+import org.apache.hadoop.io.DataOutputBuffer;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapred.TaskStatus;
+import org.apache.hadoop.thirdparty.protobuf.ByteString;
+import org.apache.hadoop.thirdparty.protobuf.ServiceException;
+
+import static 
org.apache.hadoop.ipc.internal.ShadedProtobufHelper.getRemoteException;
+
+/**
+ * Protocol helpers.
+ * <p>The lambda expressions and invokers are very similar to that of 
ShadedProtobufHelper.ipc(),
+ * but with broader exception catching.
+ */
+final class TaskUmbilicalProtocolUtils {
+
+  private TaskUmbilicalProtocolUtils() {
+  }
+
+  /*
+  Serialization helpers
+   */
+
+  /**
+   * Serialize a Writable into a protobuf ByteString.
+   * @param writable source
+   * @return data written to bytes.
+   * @throws IOException write failure.
+   */
+  static ByteString serialize(Writable writable)
+      throws IOException {
+    DataOutputBuffer dob = new DataOutputBuffer();
+    writable.write(dob);
+    return ByteString.copyFrom(dob.getData(), 0, dob.getLength());
+  }
+
+  /**
+   * Deserialize specific writable from bytes in a protobuf string.
+   * @param writable the writable instance which will be filled with the data
+   * @param bytes bytes to unmarshall.
+   * @param <T> type of the writable.
+   * @return the writable.
+   * @throws IOException read failure.
+   */
+  static <T extends Writable> T deserialize(
+      T writable, ByteString bytes) throws IOException {
+    DataInputBuffer dib = new DataInputBuffer();
+    byte[] b = bytes.toByteArray();
+    dib.reset(b, b.length);
+    writable.readFields(dib);
+    return writable;
+  }
+
+  /**
+   * Serialize a task status.
+   * @param status task to serialize
+   * @return the serialized status, including a flag to indicate status type.
+   * @throws IOException write failre.
+   */
+  static ByteString serializeTaskStatus(TaskStatus status) throws IOException {
+    DataOutputBuffer dob = new DataOutputBuffer();
+    TaskStatus.writeTaskStatusForPB(dob, status);
+    return ByteString.copyFrom(dob.getData(), 0, dob.getLength());
+  }
+
+  /**
+   * Deserialize a byte string to a matching TaskStatus implementation.
+   * @param bytes source bytes
+   * @return task status
+   * @throws IOException read failure.
+   */
+  static TaskStatus deserializeTaskStatus(ByteString bytes) throws IOException 
{
+    DataInputBuffer dib = new DataInputBuffer();
+    byte[] b = bytes.toByteArray();
+    dib.reset(b, b.length);
+    return TaskStatus.readTaskStatusFromPB(dib);
+  }
+
+  /*
+  Service invocation with exception translation.
+   */
+
+  /**
+   * Service invocation.
+   * @param <Result> type of result.
+   */
+  @FunctionalInterface
+  interface ServiceCallable<Result> {
+
+    Result apply() throws IOException, ServiceException;
+  }
+
+  /**
+   * Service invocation with void response.
+   */
+  @FunctionalInterface
+  interface ServiceVoidCallable {
+
+    void apply() throws IOException, ServiceException;
+  }
+
+  /**
+   * Invoke a service.
+   * @param callable callable
+   * @param <Result> type of result
+   * @return result
+   * @throws UncheckedIOException wrapped IOE.
+   */
+  static <Result> Result service(ServiceCallable<Result> callable) {
+    try {
+      return callable.apply();
+    } catch (ServiceException e) {
+      throw new UncheckedIOException(getRemoteException(e));
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
+  /**
+   * Invoke a service with no result.
+   * @param callable callable
+   * @throws UncheckedIOException wrapped IOE.
+   */
+  static void service(ServiceVoidCallable callable) {
+    service(() -> {
+      callable.apply();
+      return null;
+    });
+  }
+
+
+  /**
+   * Client side lambda expression.
+   * @param <Result> type of result.
+   */
+  @FunctionalInterface
+  interface ClientCallable<Result> {
+
+    Result apply() throws IOException, InterruptedException;
+  }
+
+  /**
+   * Client side lambda expression with void result.
+   */
+  @FunctionalInterface
+  interface ClientVoidCallable {
+
+    void apply() throws IOException, InterruptedException;
+  }
+
+
+  static <Result> Result translate(ClientCallable<Result> callable) throws 
ServiceException {
+    try {
+      return callable.apply();
+    } catch (IOException | InterruptedException e) {
+      throw new ServiceException(e);
+    }
+  }
+
+  static void translate(ClientVoidCallable callable) throws ServiceException {
+    translate(() -> {
+      callable.apply();
+      return null;
+    });
+  }
+
+}
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/package-info.java
similarity index 50%
copy from 
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
copy to 
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/package-info.java
index 88eeefc8e76..5904dd28dcd 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapred/protocolPB/package-info.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -16,42 +16,17 @@
  * limitations under the License.
  */
 
-package org.apache.hadoop.mapred;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.io.Writable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/**
+ * This package contains the protobuf implementation of the MR
+ * TaskUmbilicalProtocol which was originally
+ * a {@code WritableRPC} protocol.
+ * To marshall some of the complex MR datatypes, such as {@code Task},
+ * some objects are serialized to bytes
+ * and send in the RPC messages as binary objects, rather than fully
+ * defined in protobuf messages.
+ */
 
-class JvmContext implements Writable {
[email protected]
+package org.apache.hadoop.mapred.protocolPB;
 
-  public static final Logger LOG =
-      LoggerFactory.getLogger(JvmContext.class);
-  
-  JVMId jvmId;
-  String pid;
-  
-  JvmContext() {
-    jvmId = new JVMId();
-    pid = "";
-  }
-  
-  JvmContext(JVMId id, String pid) {
-    jvmId = id;
-    this.pid = pid;
-  }
-  
-  public void readFields(DataInput in) throws IOException {
-    jvmId.readFields(in);
-    this.pid = Text.readString(in);
-  }
-  
-  public void write(DataOutput out) throws IOException {
-    jvmId.write(out);
-    Text.writeString(out, pid);
-  }
-}
+import org.apache.hadoop.classification.InterfaceAudience;
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/security/authorize/MRAMPolicyProvider.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/security/authorize/MRAMPolicyProvider.java
index 24d0c2f7f92..c4ee101cf3f 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/security/authorize/MRAMPolicyProvider.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/security/authorize/MRAMPolicyProvider.java
@@ -19,7 +19,7 @@
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
-import org.apache.hadoop.mapred.TaskUmbilicalProtocol;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPB;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.v2.api.MRClientProtocolPB;
 import org.apache.hadoop.security.authorize.PolicyProvider;
@@ -36,7 +36,7 @@ public class MRAMPolicyProvider extends PolicyProvider {
       new Service[] {
     new Service(
         MRJobConfig.MR_AM_SECURITY_SERVICE_AUTHORIZATION_TASK_UMBILICAL,
-        TaskUmbilicalProtocol.class),
+        TaskUmbilicalProtocolPB.class),
     new Service(
         MRJobConfig.MR_AM_SECURITY_SERVICE_AUTHORIZATION_CLIENT,
         MRClientProtocolPB.class)
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/proto/TaskUmbilicalProtocol.proto
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/proto/TaskUmbilicalProtocol.proto
new file mode 100644
index 00000000000..61e683469f7
--- /dev/null
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/proto/TaskUmbilicalProtocol.proto
@@ -0,0 +1,187 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * These .proto interfaces are private and subject to change.
+ * Please see https://issues.apache.org/jira/browse/MAPREDUCE-6706
+ */
+
+syntax = "proto2";
+option java_package = "org.apache.hadoop.mapred.proto";
+option java_outer_classname = "TaskUmbilicalProtocolProtos";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+package hadoop.mapreduce.app;
+
+/*
+ Writable-serialized types are carried as opaque bytes, for example 
jvm_context and
+ jvm_task.
+ TaskStatus is marshalled as a byte array which also includes a boolean to 
declare
+ what subclass of TaskStatus to instantiate.
+ All parameter bytes fields are optional to handle null values.
+ */
+
+// getTask
+message GetTaskRequestProto {
+  optional bytes jvm_context = 1;
+}
+message GetTaskResponseProto {
+  optional bytes jvm_task = 1;
+}
+
+// statusUpdate
+message StatusUpdateRequestProto {
+  optional bytes task_id = 1;
+  optional bytes task_status = 2;
+}
+message StatusUpdateResponseProto {
+  required bool task_found = 1;
+  required bool preemption = 2;
+}
+
+// reportDiagnosticInfo
+message ReportDiagnosticInfoRequestProto {
+  optional bytes task_id = 1;
+  required string trace = 2;
+}
+message ReportDiagnosticInfoResponseProto {
+}
+
+// reportNextRecordRange
+message ReportNextRecordRangeRequestProto {
+  optional bytes task_id = 1;
+  optional bytes range = 2;
+}
+message ReportNextRecordRangeResponseProto {
+}
+
+// done
+message DoneRequestProto {
+  optional bytes task_id = 1;
+}
+message DoneResponseProto {
+}
+
+// commitPending
+message CommitPendingRequestProto {
+  optional bytes task_id = 1;
+  optional bytes task_status = 2;
+}
+message CommitPendingResponseProto {
+}
+
+// canCommit
+message CanCommitRequestProto {
+  optional bytes task_id = 1;
+}
+message CanCommitResponseProto {
+  required bool can_commit = 1;
+}
+
+// shuffleError
+message ShuffleErrorRequestProto {
+  optional bytes task_id = 1;
+  required string message = 2;
+}
+message ShuffleErrorResponseProto {
+}
+
+// fsError
+message FsErrorRequestProto {
+  optional bytes task_id = 1;
+  required string message = 2;
+}
+message FsErrorResponseProto {
+}
+
+// fatalError
+message FatalErrorRequestProto {
+  optional bytes task_id = 1;
+  required string message = 2;
+  required bool fast_fail = 3;
+}
+message FatalErrorResponseProto {
+}
+
+// getMapCompletionEvents
+message GetMapCompletionEventsRequestProto {
+  optional bytes job_id = 1;
+  required int32 from_index = 2;
+  required int32 max_locs = 3;
+  optional bytes task_attempt_id = 4;
+}
+message GetMapCompletionEventsResponseProto {
+  optional bytes events_update = 1;
+}
+
+// preempted
+message PreemptedRequestProto {
+  optional bytes task_id = 1;
+  optional bytes task_status = 2;
+}
+message PreemptedResponseProto {
+}
+
+// getCheckpointID
+message GetCheckpointIDRequestProto {
+  optional bytes task_id = 1;
+}
+message GetCheckpointIDResponseProto {
+  optional bytes checkpoint_id = 1;
+}
+
+// setCheckpointID
+message SetCheckpointIDRequestProto {
+  optional bytes task_id = 1;
+  optional bytes checkpoint_id = 2;
+}
+message SetCheckpointIDResponseProto {
+}
+
+/* Task Umbilical Protocol. */
+
+service TaskUmbilicalProtocolService {
+  rpc getTask(GetTaskRequestProto)
+      returns (GetTaskResponseProto);
+  rpc statusUpdate(StatusUpdateRequestProto)
+      returns (StatusUpdateResponseProto);
+  rpc reportDiagnosticInfo(ReportDiagnosticInfoRequestProto)
+      returns (ReportDiagnosticInfoResponseProto);
+  rpc reportNextRecordRange(ReportNextRecordRangeRequestProto)
+      returns (ReportNextRecordRangeResponseProto);
+  rpc done(DoneRequestProto)
+      returns (DoneResponseProto);
+  rpc commitPending(CommitPendingRequestProto)
+      returns (CommitPendingResponseProto);
+  rpc canCommit(CanCommitRequestProto)
+      returns (CanCommitResponseProto);
+  rpc shuffleError(ShuffleErrorRequestProto)
+      returns (ShuffleErrorResponseProto);
+  rpc fsError(FsErrorRequestProto)
+      returns (FsErrorResponseProto);
+  rpc fatalError(FatalErrorRequestProto)
+      returns (FatalErrorResponseProto);
+  rpc getMapCompletionEvents(GetMapCompletionEventsRequestProto)
+      returns (GetMapCompletionEventsResponseProto);
+  rpc preempted(PreemptedRequestProto)
+      returns (PreemptedResponseProto);
+  rpc getCheckpointID(GetCheckpointIDRequestProto)
+      returns (GetCheckpointIDResponseProto);
+  rpc setCheckpointID(SetCheckpointIDRequestProto)
+      returns (SetCheckpointIDResponseProto);
+}
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
index 88eeefc8e76..4b7d379fc8c 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/JvmContext.java
@@ -27,7 +27,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-class JvmContext implements Writable {
+public class JvmContext implements Writable {
 
   public static final Logger LOG =
       LoggerFactory.getLogger(JvmContext.class);
@@ -35,12 +35,12 @@ class JvmContext implements Writable {
   JVMId jvmId;
   String pid;
   
-  JvmContext() {
+  public JvmContext() {
     jvmId = new JVMId();
     pid = "";
   }
   
-  JvmContext(JVMId id, String pid) {
+  public JvmContext(JVMId id, String pid) {
     jvmId = id;
     this.pid = pid;
   }
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java
index 9d4e7354f0d..071f33e9e1a 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/SortedRanges.java
@@ -35,7 +35,7 @@
  * Provides the SkipRangeIterator, which skips the Ranges 
  * stored in this object.
  */
-class SortedRanges implements Writable{
+public class SortedRanges implements Writable{
   
   private static final Logger LOG =
       LoggerFactory.getLogger(SortedRanges.class);
@@ -221,7 +221,7 @@ public String toString() {
    * A Range can be of 0 length also. The Range stores indices 
    * of type long.
    */
-  static class Range implements Comparable<Range>, Writable{
+  public static class Range implements Comparable<Range>, Writable{
     private long startIndex;
     private long length;
         
@@ -233,7 +233,7 @@ static class Range implements Comparable<Range>, Writable{
       this.length = length;
     }
     
-    Range() {
+    public Range() {
       this(0,0);
     }
     
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/TaskStatus.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/TaskStatus.java
index 7496d7c6c25..88d67d6ff6d 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/TaskStatus.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/TaskStatus.java
@@ -519,8 +519,52 @@ static TaskStatus createTaskStatus(boolean isMap, 
TaskAttemptID taskId,
                                           taskTracker, phase, counters);
   }
   
+  /**
+   * Enum identifying the concrete type of a {@link TaskStatus} for 
serialization.
+   */
+  public enum TaskStatusKind {
+    MapTaskStatus,
+    ReduceTaskStatus
+  }
+
   static TaskStatus createTaskStatus(boolean isMap) {
-    return (isMap) ? new MapTaskStatus() : new ReduceTaskStatus();
+    return createTaskStatus(
+        isMap ? TaskStatusKind.MapTaskStatus : 
TaskStatusKind.ReduceTaskStatus);
+  }
+
+  static TaskStatus createTaskStatus(TaskStatusKind kind) {
+    return kind == TaskStatusKind.MapTaskStatus
+        ? new MapTaskStatus() : new ReduceTaskStatus();
+  }
+
+  /**
+   * Write a TaskStatus to a DataOutput, prefixed by a {@link TaskStatusKind} 
discriminator.
+   * Used by the Protobuf-based RPC layer to serialize TaskStatus values.
+   * @param out output stream
+   * @param status status to write (must not be null)
+   * @throws IOException on I/O error
+   */
+  public static void writeTaskStatusForPB(DataOutput out, TaskStatus status)
+      throws IOException {
+    TaskStatusKind kind = status.getIsMap()
+        ? TaskStatusKind.MapTaskStatus : TaskStatusKind.ReduceTaskStatus;
+    out.writeByte(kind.ordinal());
+    status.write(out);
+  }
+
+  /**
+   * Read a TaskStatus that was written with {@link #writeTaskStatusForPB}.
+   * @param in input stream
+   * @return the deserialized TaskStatus
+   * @throws IOException on I/O error
+   */
+  public static TaskStatus readTaskStatusFromPB(DataInput in)
+      throws IOException {
+    int ordinal = in.readByte() & 0xFF;
+    TaskStatusKind kind = TaskStatusKind.values()[ordinal];
+    TaskStatus status = createTaskStatus(kind);
+    status.readFields(in);
+    return status;
   }
 
 }
diff --git 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/security/TestUmbilicalProtocolWithJobToken.java
 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/security/TestUmbilicalProtocolWithJobToken.java
index 56f95469b39..d8fdd174f95 100644
--- 
a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/security/TestUmbilicalProtocolWithJobToken.java
+++ 
b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/security/TestUmbilicalProtocolWithJobToken.java
@@ -19,12 +19,11 @@
 package org.apache.hadoop.mapreduce.security;
 
 import static 
org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.doReturn;
 
+import java.io.Closeable;
 import java.net.InetSocketAddress;
 import java.security.PrivilegedExceptionAction;
 
@@ -33,10 +32,15 @@
 
 import org.apache.hadoop.test.GenericTestUtils;
 import org.apache.hadoop.ipc.Client;
+import org.apache.hadoop.ipc.ProtobufRpcEngine2;
 import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.ipc.Server;
-import org.apache.hadoop.ipc.ProtocolSignature;
+import org.apache.hadoop.mapred.AMFeedback;
 import org.apache.hadoop.mapred.TaskUmbilicalProtocol;
+import org.apache.hadoop.mapred.proto.TaskUmbilicalProtocolProtos;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPB;
+import org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolPBClientImpl;
+import 
org.apache.hadoop.mapred.protocolPB.TaskUmbilicalProtocolServerSideTranslatorPB;
 import org.apache.hadoop.mapreduce.security.token.JobTokenIdentifier;
 import org.apache.hadoop.mapreduce.security.token.JobTokenSecretManager;
 import org.apache.hadoop.net.NetUtils;
@@ -51,10 +55,10 @@
 import org.junit.jupiter.api.Test;
 import static org.slf4j.LoggerFactory.getLogger;
 
-/** Unit tests for using Job Token over RPC. 
- * 
+/** Unit tests for using Job Token over RPC.
+ *
  * System properties required:
- * 
-Djava.security.krb5.conf=.../hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/target/test-classes/krb5.conf
 
+ * 
-Djava.security.krb5.conf=.../hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/target/test-classes/krb5.conf
  * -Djava.net.preferIPv4Stack=true
  */
 public class TestUmbilicalProtocolWithJobToken {
@@ -80,16 +84,22 @@ public class TestUmbilicalProtocolWithJobToken {
   @Test
   public void testJobTokenRpc() throws Exception {
     TaskUmbilicalProtocol mockTT = mock(TaskUmbilicalProtocol.class);
-    doReturn(TaskUmbilicalProtocol.versionID)
-      .when(mockTT).getProtocolVersion(anyString(), anyLong());
-    doReturn(ProtocolSignature.getProtocolSignature(
-        mockTT, TaskUmbilicalProtocol.class.getName(),
-        TaskUmbilicalProtocol.versionID, 0))
-      .when(mockTT).getProtocolSignature(anyString(), anyLong(), anyInt());
+    AMFeedback feedback = new AMFeedback();
+    feedback.setTaskFound(true);
+    doReturn(feedback).when(mockTT).statusUpdate(any(), any());
+
+    TaskUmbilicalProtocolServerSideTranslatorPB translator =
+        new TaskUmbilicalProtocolServerSideTranslatorPB(mockTT);
+    org.apache.hadoop.thirdparty.protobuf.BlockingService blockingService =
+        TaskUmbilicalProtocolProtos.TaskUmbilicalProtocolService
+            .newReflectiveBlockingService(translator);
 
     JobTokenSecretManager sm = new JobTokenSecretManager();
+    RPC.setProtocolEngine(conf, TaskUmbilicalProtocolPB.class,
+        ProtobufRpcEngine2.class);
     final Server server = new RPC.Builder(conf)
-        .setProtocol(TaskUmbilicalProtocol.class).setInstance(mockTT)
+        .setProtocol(TaskUmbilicalProtocolPB.class)
+        .setInstance(blockingService)
         .setBindAddress(ADDRESS).setPort(0).setNumHandlers(5).setVerbose(true)
         .setSecretManager(sm).build();
 
@@ -109,14 +119,16 @@ public void testJobTokenRpc() throws Exception {
       public Object run() throws Exception {
         TaskUmbilicalProtocol proxy = null;
         try {
-          proxy = (TaskUmbilicalProtocol) RPC.getProxy(
-              TaskUmbilicalProtocol.class, TaskUmbilicalProtocol.versionID,
+          TaskUmbilicalProtocolPB pbProxy = RPC.getProxy(
+              TaskUmbilicalProtocolPB.class,
+              RPC.getProtocolVersion(TaskUmbilicalProtocolPB.class),
               addr, conf);
+          proxy = new TaskUmbilicalProtocolPBClientImpl(pbProxy);
           proxy.statusUpdate(null, null);
         } finally {
           server.stop();
-          if (proxy != null) {
-            RPC.stopProxy(proxy);
+          if (proxy instanceof Closeable closeable) {
+            closeable.close();
           }
         }
         return null;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to