1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.yarn.api.records.impl.pb; 20 21 import java.io.IOException; 22 import java.io.PrintWriter; 23 import java.io.StringWriter; 24 import java.lang.reflect.Constructor; 25 import java.lang.reflect.InvocationTargetException; 26 27 import org.apache.hadoop.yarn.api.records.SerializedException; 28 import org.apache.hadoop.yarn.exceptions.YarnException; 29 import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; 30 import org.apache.hadoop.yarn.proto.YarnProtos.SerializedExceptionProto; 31 import org.apache.hadoop.yarn.proto.YarnProtos.SerializedExceptionProtoOrBuilder; 32 33 public class SerializedExceptionPBImpl extends SerializedException { 34 35 SerializedExceptionProto proto = null; 36 SerializedExceptionProto.Builder builder = 37 SerializedExceptionProto.newBuilder(); 38 boolean viaProto = false; 39 SerializedExceptionPBImpl()40 public SerializedExceptionPBImpl() { 41 } 42 SerializedExceptionPBImpl(SerializedExceptionProto proto)43 public SerializedExceptionPBImpl(SerializedExceptionProto proto) { 44 this.proto = proto; 45 viaProto = true; 46 } 47 SerializedExceptionPBImpl(Throwable t)48 private SerializedExceptionPBImpl(Throwable t) { 49 init(t); 50 } 51 init(String message)52 public void init(String message) { 53 maybeInitBuilder(); 54 builder.setMessage(message); 55 } 56 init(Throwable t)57 public void init(Throwable t) { 58 maybeInitBuilder(); 59 if (t == null) { 60 return; 61 } 62 63 if (t.getCause() == null) { 64 } else { 65 builder.setCause(new SerializedExceptionPBImpl(t.getCause()).getProto()); 66 } 67 StringWriter sw = new StringWriter(); 68 PrintWriter pw = new PrintWriter(sw); 69 t.printStackTrace(pw); 70 pw.close(); 71 if (sw.toString() != null) 72 builder.setTrace(sw.toString()); 73 if (t.getMessage() != null) 74 builder.setMessage(t.getMessage()); 75 builder.setClassName(t.getClass().getCanonicalName()); 76 } 77 init(String message, Throwable t)78 public void init(String message, Throwable t) { 79 init(t); 80 if (message != null) 81 builder.setMessage(message); 82 } 83 84 @SuppressWarnings("unchecked") 85 @Override deSerialize()86 public Throwable deSerialize() { 87 88 SerializedException cause = getCause(); 89 SerializedExceptionProtoOrBuilder p = viaProto ? proto : builder; 90 Class<?> realClass = null; 91 try { 92 realClass = Class.forName(p.getClassName()); 93 } catch (ClassNotFoundException e) { 94 throw new YarnRuntimeException(e); 95 } 96 Class classType = null; 97 if (YarnException.class.isAssignableFrom(realClass)) { 98 classType = YarnException.class; 99 } else if (IOException.class.isAssignableFrom(realClass)) { 100 classType = IOException.class; 101 } else if (RuntimeException.class.isAssignableFrom(realClass)) { 102 classType = RuntimeException.class; 103 } else { 104 classType = Exception.class; 105 } 106 return instantiateException(realClass.asSubclass(classType), getMessage(), 107 cause == null ? null : cause.deSerialize()); 108 } 109 110 @Override getMessage()111 public String getMessage() { 112 SerializedExceptionProtoOrBuilder p = viaProto ? proto : builder; 113 return p.getMessage(); 114 } 115 116 @Override getRemoteTrace()117 public String getRemoteTrace() { 118 SerializedExceptionProtoOrBuilder p = viaProto ? proto : builder; 119 return p.getTrace(); 120 } 121 122 @Override getCause()123 public SerializedException getCause() { 124 SerializedExceptionProtoOrBuilder p = viaProto ? proto : builder; 125 if (p.hasCause()) { 126 return new SerializedExceptionPBImpl(p.getCause()); 127 } else { 128 return null; 129 } 130 } 131 getProto()132 public SerializedExceptionProto getProto() { 133 proto = viaProto ? proto : builder.build(); 134 viaProto = true; 135 return proto; 136 } 137 138 @Override hashCode()139 public int hashCode() { 140 return getProto().hashCode(); 141 } 142 143 @Override equals(Object other)144 public boolean equals(Object other) { 145 if (other == null) { 146 return false; 147 } 148 if (other.getClass().isAssignableFrom(this.getClass())) { 149 return this.getProto().equals(this.getClass().cast(other).getProto()); 150 } 151 return false; 152 } 153 maybeInitBuilder()154 private void maybeInitBuilder() { 155 if (viaProto || builder == null) { 156 builder = SerializedExceptionProto.newBuilder(proto); 157 } 158 viaProto = false; 159 } 160 instantiateException( Class<? extends T> cls, String message, Throwable cause)161 private static <T extends Throwable> T instantiateException( 162 Class<? extends T> cls, String message, Throwable cause) { 163 Constructor<? extends T> cn; 164 T ex = null; 165 try { 166 cn = cls.getConstructor(String.class); 167 cn.setAccessible(true); 168 ex = cn.newInstance(message); 169 ex.initCause(cause); 170 } catch (SecurityException e) { 171 throw new YarnRuntimeException(e); 172 } catch (NoSuchMethodException e) { 173 throw new YarnRuntimeException(e); 174 } catch (IllegalArgumentException e) { 175 throw new YarnRuntimeException(e); 176 } catch (InstantiationException e) { 177 throw new YarnRuntimeException(e); 178 } catch (IllegalAccessException e) { 179 throw new YarnRuntimeException(e); 180 } catch (InvocationTargetException e) { 181 throw new YarnRuntimeException(e); 182 } 183 return ex; 184 } 185 }