|
@@ -19,6 +19,7 @@
|
|
package org.apache.hadoop.ipc;
|
|
package org.apache.hadoop.ipc;
|
|
|
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.lang.reflect.Constructor;
|
|
|
|
|
|
public class RemoteException extends IOException {
|
|
public class RemoteException extends IOException {
|
|
private String className;
|
|
private String className;
|
|
@@ -36,50 +37,53 @@ public class RemoteException extends IOException {
|
|
* If this remote exception wraps up one of the lookupTypes
|
|
* If this remote exception wraps up one of the lookupTypes
|
|
* then return this exception.
|
|
* then return this exception.
|
|
* <p>
|
|
* <p>
|
|
- * Unwraps any IOException that has a default constructor.
|
|
|
|
|
|
+ * Unwraps any IOException.
|
|
*
|
|
*
|
|
* @param lookupTypes the desired exception class.
|
|
* @param lookupTypes the desired exception class.
|
|
* @return IOException, which is either the lookupClass exception or this.
|
|
* @return IOException, which is either the lookupClass exception or this.
|
|
*/
|
|
*/
|
|
- public IOException unwrapRemoteException(Class... lookupTypes) {
|
|
|
|
|
|
+ public IOException unwrapRemoteException(Class<?>... lookupTypes) {
|
|
if(lookupTypes == null)
|
|
if(lookupTypes == null)
|
|
return this;
|
|
return this;
|
|
- for(Class lookupClass : lookupTypes) {
|
|
|
|
- if(!IOException.class.isAssignableFrom(lookupClass))
|
|
|
|
|
|
+ for(Class<?> lookupClass : lookupTypes) {
|
|
|
|
+ if(!lookupClass.getName().equals(getClassName()))
|
|
continue;
|
|
continue;
|
|
- if(lookupClass.getName().equals(getClassName())) {
|
|
|
|
- try {
|
|
|
|
- IOException ex = (IOException)lookupClass.newInstance();
|
|
|
|
- ex.initCause(this);
|
|
|
|
- return ex;
|
|
|
|
- } catch(Exception e) {
|
|
|
|
- // cannot instantiate lookupClass, just return this
|
|
|
|
- return this;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ try {
|
|
|
|
+ return instantiateException(lookupClass.asSubclass(IOException.class));
|
|
|
|
+ } catch(Exception e) {
|
|
|
|
+ // cannot instantiate lookupClass, just return this
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ // wrapped up exception is not in lookupTypes, just return this
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * If this remote exception wraps an IOException that has a default
|
|
|
|
- * contructor then instantiate and return the original exception.
|
|
|
|
- * Otherwise return this.
|
|
|
|
|
|
+ * Instantiate and return the exception wrapped up by this remote exception.
|
|
|
|
+ *
|
|
|
|
+ * <p> This unwraps any <code>Throwable</code> that has a constructor taking
|
|
|
|
+ * a <code>String</code> as a parameter.
|
|
|
|
+ * Otherwise it returns this.
|
|
*
|
|
*
|
|
- * @return IOException
|
|
|
|
|
|
+ * @return <code>Throwable
|
|
*/
|
|
*/
|
|
public IOException unwrapRemoteException() {
|
|
public IOException unwrapRemoteException() {
|
|
- IOException ex;
|
|
|
|
try {
|
|
try {
|
|
- Class realClass = Class.forName(getClassName());
|
|
|
|
- if(!IOException.class.isAssignableFrom(realClass))
|
|
|
|
- return this;
|
|
|
|
- ex = (IOException)realClass.newInstance();
|
|
|
|
- ex.initCause(this);
|
|
|
|
- return ex;
|
|
|
|
|
|
+ Class<?> realClass = Class.forName(getClassName());
|
|
|
|
+ return instantiateException(realClass.asSubclass(IOException.class));
|
|
} catch(Exception e) {
|
|
} catch(Exception e) {
|
|
- // cannot instantiate the original exception, just throw this
|
|
|
|
|
|
+ // cannot instantiate the original exception, just return this
|
|
}
|
|
}
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private IOException instantiateException(Class<? extends IOException> cls)
|
|
|
|
+ throws Exception {
|
|
|
|
+ Constructor<? extends IOException> cn = cls.getConstructor(String.class);
|
|
|
|
+ cn.setAccessible(true);
|
|
|
|
+ IOException ex = cn.newInstance(this.getMessage());
|
|
|
|
+ ex.initCause(this);
|
|
|
|
+ return ex;
|
|
|
|
+ }
|
|
}
|
|
}
|