Przeglądaj źródła

YARN-3745. SerializedException should also try to instantiate internal
exception with the default constructor. Contributed by Lavkesh Lahngir.

Devaraj K 10 lat temu
rodzic
commit
b381f88c71

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -556,6 +556,9 @@ Release 2.8.0 - UNRELEASED
     YARN-3826. Race condition in ResourceTrackerService leads to
     wrong diagnostics messages. (Chengbing Liu via devaraj)
 
+    YARN-3745. SerializedException should also try to instantiate internal
+    exception with the default constructor. (Lavkesh Lahngir via devaraj)
+
 Release 2.7.1 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 21 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/SerializedExceptionPBImpl.java

@@ -158,15 +158,31 @@ public class SerializedExceptionPBImpl extends SerializedException {
     viaProto = false;
   }
 
+  private static <T extends Throwable> T instantiateExceptionImpl(
+      String message, Class<? extends T> cls, Throwable cause)
+      throws NoSuchMethodException, InstantiationException,
+      IllegalAccessException, InvocationTargetException {
+    Constructor<? extends T> cn;
+    T ex = null;
+    cn =
+        cls.getConstructor(message == null ? new Class[0]
+            : new Class[] {String.class});
+    cn.setAccessible(true);
+    ex = message == null ? cn.newInstance() : cn.newInstance(message);
+    ex.initCause(cause);
+    return ex;
+  }
+
   private static <T extends Throwable> T instantiateException(
       Class<? extends T> cls, String message, Throwable cause) {
-    Constructor<? extends T> cn;
     T ex = null;
     try {
-      cn = cls.getConstructor(String.class);
-      cn.setAccessible(true);
-      ex = cn.newInstance(message);
-      ex.initCause(cause);
+      // Try constructor with String argument, if it fails, try default.
+      try {
+        ex = instantiateExceptionImpl(message, cls, cause);
+      } catch (NoSuchMethodException e) {
+        ex = instantiateExceptionImpl(null, cls, cause);
+      }
     } catch (SecurityException e) {
       throw new YarnRuntimeException(e);
     } catch (NoSuchMethodException e) {

+ 11 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/records/impl/pb/TestSerializedExceptionPBImpl.java

@@ -18,6 +18,8 @@
 
 package org.apache.hadoop.yarn.api.records.impl.pb;
 
+import java.nio.channels.ClosedChannelException;
+
 import org.junit.Assert;
 import org.apache.hadoop.yarn.api.records.impl.pb.SerializedExceptionPBImpl;
 import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
@@ -54,6 +56,15 @@ public class TestSerializedExceptionPBImpl {
     Assert.assertEquals(ex.toString(), pb.deSerialize().toString());
   }
 
+  @Test
+  public void testDeserializeWithDefaultConstructor() {
+    // Init SerializedException with an Exception with default constructor.
+    ClosedChannelException ex = new ClosedChannelException();
+    SerializedExceptionPBImpl pb = new SerializedExceptionPBImpl();
+    pb.init(ex);
+    Assert.assertEquals(ex.getClass(), pb.deSerialize().getClass());
+  }
+
   @Test
   public void testBeforeInit() throws Exception {
     SerializedExceptionProto defaultProto =