diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java index 619dcd6..f4fff80 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java @@ -1204,17 +1204,22 @@ public final class ProtobufUtil { * @throws IOException if failed to deserialize the parameter */ @SuppressWarnings("unchecked") - public static Throwable toException( - final NameBytesPair parameter) throws IOException { + public static Throwable toException(final NameBytesPair parameter) throws IOException { if (parameter == null || !parameter.hasValue()) return null; String desc = parameter.getValue().toStringUtf8(); String type = parameter.getName(); try { Class c = (Class)Class.forName(type, true, CLASS_LOADER); - Constructor cn = - c.getDeclaredConstructor(String.class); - return cn.newInstance(desc); + Constructor cn = null; + try { + cn = c.getDeclaredConstructor(String.class); + return cn.newInstance(desc); + } catch (NoSuchMethodException e) { + // Could be a raw RemoteException. See HBASE-8987. + cn = c.getDeclaredConstructor(String.class, String.class); + return cn.newInstance(type, desc); + } } catch (Exception e) { throw new IOException(e); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/protobuf/TestProtobufUtil.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/protobuf/TestProtobufUtil.java index a686ba2..6237f64 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/protobuf/TestProtobufUtil.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/protobuf/TestProtobufUtil.java @@ -36,6 +36,7 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Col import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.DeleteType; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameBytesPair; import org.apache.hadoop.hbase.util.Bytes; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -47,6 +48,20 @@ import com.google.protobuf.ByteString; */ @Category(SmallTests.class) public class TestProtobufUtil { + @Test + public void testException() throws IOException { + NameBytesPair.Builder builder = NameBytesPair.newBuilder(); + final String omg = "OMG!!!"; + builder.setName("java.io.IOException"); + builder.setValue(ByteString.copyFrom(Bytes.toBytes(omg))); + Throwable t = ProtobufUtil.toException(builder.build()); + assertEquals(omg, t.getMessage()); + builder.clear(); + builder.setName("org.apache.hadoop.ipc.RemoteException"); + builder.setValue(ByteString.copyFrom(Bytes.toBytes(omg))); + t = ProtobufUtil.toException(builder.build()); + assertEquals(omg, t.getMessage()); + } /** * Test basic Get conversions.