Exception handling in HBase is broken over client server connections

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/trunk/src/contrib/hbase@555282 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jim Kellerman 2007-07-11 14:23:00 +00:00
parent 6f42c1f60f
commit f613907a98
4 changed files with 256 additions and 127 deletions

View File

@ -55,5 +55,6 @@ Trunk (unreleased changes)
HADOOP-1466 Clean up visibility and javadoc issues in HBase. HADOOP-1466 Clean up visibility and javadoc issues in HBase.
33. HADOOP-1538 Provide capability for client specified time stamps in HBase 33. HADOOP-1538 Provide capability for client specified time stamps in HBase
HADOOP-1466 Clean up visibility and javadoc issues in HBase. HADOOP-1466 Clean up visibility and javadoc issues in HBase.
34. HADOOP-1589 Exception handling in HBase is broken over client server connections

View File

@ -15,6 +15,8 @@
*/ */
package org.apache.hadoop.hbase; package org.apache.hadoop.hbase;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -154,31 +156,6 @@ public class HClient implements HConstants {
return result; return result;
} }
protected void handleRemoteException(RemoteException e) throws IOException {
String msg = e.getMessage();
if(e.getClassName().equals("org.apache.hadoop.hbase.InvalidColumnNameException")) {
throw new InvalidColumnNameException(msg);
} else if(e.getClassName().equals("org.apache.hadoop.hbase.LockException")) {
throw new LockException(msg);
} else if(e.getClassName().equals("org.apache.hadoop.hbase.MasterNotRunningException")) {
throw new MasterNotRunningException(msg);
} else if(e.getClassName().equals("org.apache.hadoop.hbase.NoServerForRegionException")) {
throw new NoServerForRegionException(msg);
} else if(e.getClassName().equals("org.apache.hadoop.hbase.NotServingRegionException")) {
throw new NotServingRegionException(msg);
} else if(e.getClassName().equals("org.apache.hadoop.hbase.TableNotDisabledException")) {
throw new TableNotDisabledException(msg);
} else {
throw e;
}
}
/* Find the address of the master and connect to it /* Find the address of the master and connect to it
*/ */
protected void checkMaster() throws MasterNotRunningException { protected void checkMaster() throws MasterNotRunningException {
@ -284,8 +261,8 @@ public class HClient implements HConstants {
checkMaster(); checkMaster();
try { try {
this.master.createTable(desc); this.master.createTable(desc);
} catch (RemoteException e) { } catch (Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -302,8 +279,8 @@ public class HClient implements HConstants {
try { try {
this.master.deleteTable(tableName); this.master.deleteTable(tableName);
} catch(RemoteException e) { } catch(Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
// Wait until first region is deleted // Wait until first region is deleted
@ -334,12 +311,17 @@ public class HClient implements HConstants {
break; break;
} }
} catch (Exception ex) {
if(tries == numRetries - 1) { // no more tries left
RemoteExceptionHandler.handleRemoteException(ex);
}
} finally { } finally {
if(scannerId != -1L) { if(scannerId != -1L) {
try { try {
server.close(scannerId); server.close(scannerId);
} catch(Exception e) { } catch(Exception ex) {
LOG.warn(e); LOG.warn(ex);
} }
} }
} }
@ -367,8 +349,8 @@ public class HClient implements HConstants {
try { try {
this.master.addColumn(tableName, column); this.master.addColumn(tableName, column);
} catch(RemoteException e) { } catch (Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -386,8 +368,8 @@ public class HClient implements HConstants {
try { try {
this.master.deleteColumn(tableName, columnName); this.master.deleteColumn(tableName, columnName);
} catch(RemoteException e) { } catch(Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -405,8 +387,8 @@ public class HClient implements HConstants {
try { try {
this.master.enableTable(tableName); this.master.enableTable(tableName);
} catch(RemoteException e) { } catch(Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
// Wait until first region is enabled // Wait until first region is enabled
@ -447,6 +429,11 @@ public class HClient implements HConstants {
break; break;
} }
} catch (Exception e) {
if(tries == numRetries - 1) { // no more retries
RemoteExceptionHandler.handleRemoteException(e);
}
} finally { } finally {
if(scannerId != -1L) { if(scannerId != -1L) {
try { try {
@ -488,8 +475,8 @@ public class HClient implements HConstants {
try { try {
this.master.disableTable(tableName); this.master.disableTable(tableName);
} catch(RemoteException e) { } catch(Exception e) {
handleRemoteException(e); RemoteExceptionHandler.handleRemoteException(e);
} }
// Wait until first region is disabled // Wait until first region is disabled
@ -530,6 +517,11 @@ public class HClient implements HConstants {
break; break;
} }
} catch(Exception e) {
if(tries == numRetries - 1) { // no more retries
RemoteExceptionHandler.handleRemoteException(e);
}
} finally { } finally {
if(scannerId != -1L) { if(scannerId != -1L) {
try { try {
@ -561,7 +553,11 @@ public class HClient implements HConstants {
*/ */
public synchronized void shutdown() throws IOException { public synchronized void shutdown() throws IOException {
checkMaster(); checkMaster();
this.master.shutdown(); try {
this.master.shutdown();
} catch(Exception e) {
RemoteExceptionHandler.handleRemoteException(e);
}
} }
/* /*
@ -741,10 +737,10 @@ public class HClient implements HConstants {
try { try {
rootRegion.getRegionInfo(HGlobals.rootRegionInfo.regionName); rootRegion.getRegionInfo(HGlobals.rootRegionInfo.regionName);
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
// Don't bother sleeping. We've run out of retries. // Don't bother sleeping. We've run out of retries.
break; RemoteExceptionHandler.handleRemoteException(e);
} }
// Sleep and retry finding root region. // Sleep and retry finding root region.
@ -822,13 +818,13 @@ public class HClient implements HConstants {
if(servers.size() == 0) { if(servers.size() == 0) {
// If we didn't find any servers then the table does not exist // If we didn't find any servers then the table does not exist
throw new RegionNotFoundException("table '" + tableName + throw new RegionNotFoundException("table '" + tableName +
"' does not exist in " + t); "' does not exist in " + t);
} }
// We found at least one server for the table and now we're done. // We found at least one server for the table and now we're done.
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Found " + servers.size() + " server(s) for " + LOG.debug("Found " + servers.size() + " server(s) for " +
"location: " + t + " for tablename " + tableName); "location: " + t + " for tablename " + tableName);
} }
break; break;
} }
@ -868,19 +864,24 @@ public class HClient implements HConstants {
servers.put(regionInfo.startKey, servers.put(regionInfo.startKey,
new RegionLocation(regionInfo, new HServerAddress(serverAddress))); new RegionLocation(regionInfo, new HServerAddress(serverAddress)));
} }
} catch (Exception e) {
if(tries == numRetries - 1) { // no retries left
RemoteExceptionHandler.handleRemoteException(e);
}
} finally { } finally {
if(scannerId != -1L) { if(scannerId != -1L) {
try { try {
server.close(scannerId); server.close(scannerId);
} catch(Exception e) { } catch(Exception ex) {
LOG.warn(e); LOG.warn(ex);
} }
} }
} }
if(servers.size() == 0 && tries == this.numRetries - 1) { if(servers.size() == 0 && tries == this.numRetries - 1) {
throw new NoServerForRegionException("failed to find server for " throw new NoServerForRegionException("failed to find server for "
+ tableName + " after " + this.numRetries + " retries"); + tableName + " after " + this.numRetries + " retries");
} }
if (servers.size() <= 0) { if (servers.size() <= 0) {
@ -891,7 +892,7 @@ public class HClient implements HConstants {
} }
try { try {
Thread.sleep(this.pause); Thread.sleep(this.pause);
} catch (InterruptedException e) { } catch (InterruptedException ie) {
// continue // continue
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@ -907,8 +908,8 @@ public class HClient implements HConstants {
* @param regionServer - the server to connect to * @param regionServer - the server to connect to
* @throws IOException * @throws IOException
*/ */
protected synchronized HRegionInterface getHRegionConnection( protected synchronized HRegionInterface getHRegionConnection (
HServerAddress regionServer) throws IOException{ HServerAddress regionServer) throws IOException {
getRegionServerInterface(); getRegionServerInterface();
@ -918,22 +919,29 @@ public class HClient implements HConstants {
if (server == null) { // Get a connection if (server == null) { // Get a connection
long versionId = 0; long versionId = 0;
try { try {
versionId = serverInterfaceClass.getDeclaredField("versionID").getLong(server); versionId =
serverInterfaceClass.getDeclaredField("versionID").getLong(server);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
// Should never happen unless visibility of versionID changes // Should never happen unless visibility of versionID changes
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Unable to open a connection to a " + serverInterfaceClass.getName() + " server.", e); "Unable to open a connection to a " + serverInterfaceClass.getName()
+ " server.", e);
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
// Should never happen unless versionID field name changes in HRegionInterface // Should never happen unless versionID field name changes in HRegionInterface
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Unable to open a connection to a " + serverInterfaceClass.getName() + " server.", e); "Unable to open a connection to a " + serverInterfaceClass.getName()
+ " server.", e);
} }
server = (HRegionInterface) RPC.waitForProxy( try {
serverInterfaceClass, server = (HRegionInterface) RPC.waitForProxy(serverInterfaceClass,
versionId, versionId, regionServer.getInetSocketAddress(), this.conf);
regionServer.getInetSocketAddress(),
this.conf); } catch (Exception e) {
RemoteExceptionHandler.handleRemoteException(e);
}
this.servers.put(regionServer.toString(), server); this.servers.put(regionServer.toString(), server);
} }
@ -988,6 +996,9 @@ public class HClient implements HConstants {
} }
} }
} }
} catch (Exception ex) {
RemoteExceptionHandler.handleRemoteException(ex);
} finally { } finally {
if(scannerId != -1L) { if(scannerId != -1L) {
server.close(scannerId); server.close(scannerId);
@ -1046,19 +1057,26 @@ public class HClient implements HConstants {
* @throws IOException * @throws IOException
*/ */
public byte[] get(Text row, Text column) throws IOException { public byte[] get(Text row, Text column) throws IOException {
RegionLocation info = null;
byte [] value = null; byte [] value = null;
for(int tries = 0; tries < numRetries && info == null; tries++) { for(int tries = 0; tries < numRetries; tries++) {
info = getRegionLocation(row); RegionLocation info = getRegionLocation(row);
HRegionInterface server = getHRegionConnection(info.serverAddress);
try { try {
value = getHRegionConnection(info.serverAddress). value = server.get(info.regionInfo.regionName, row, column);
get(info.regionInfo.regionName, row, column); break;
} catch (NotServingRegionException e) {
} catch (Exception e) {
if (tries == numRetries - 1) { if (tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
findRegion(info); findRegion(info);
} }
try {
Thread.sleep(this.pause);
} catch (InterruptedException x) {
// continue
}
} }
return value; return value;
} }
@ -1073,20 +1091,28 @@ public class HClient implements HConstants {
* @throws IOException * @throws IOException
*/ */
public byte[][] get(Text row, Text column, int numVersions) throws IOException { public byte[][] get(Text row, Text column, int numVersions) throws IOException {
RegionLocation info = null;
byte [][] values = null; byte [][] values = null;
for(int tries = 0; tries < numRetries && info == null; tries++) { for(int tries = 0; tries < numRetries; tries++) {
info = getRegionLocation(row); RegionLocation info = getRegionLocation(row);
HRegionInterface server = getHRegionConnection(info.serverAddress);
try { try {
values = getHRegionConnection(info.serverAddress).get( values = server.get(info.regionInfo.regionName, row, column, numVersions);
info.regionInfo.regionName, row, column, numVersions); break;
} catch(NotServingRegionException e) {
} catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
// No more tries // No more tries
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
findRegion(info); findRegion(info);
} }
try {
Thread.sleep(this.pause);
} catch (InterruptedException x) {
// continue
}
} }
if(values != null) { if(values != null) {
@ -1112,21 +1138,27 @@ public class HClient implements HConstants {
*/ */
public byte[][] get(Text row, Text column, long timestamp, int numVersions) public byte[][] get(Text row, Text column, long timestamp, int numVersions)
throws IOException { throws IOException {
RegionLocation info = null;
byte [][] values = null; byte [][] values = null;
for(int tries = 0; tries < numRetries && info == null; tries++) { for(int tries = 0; tries < numRetries; tries++) {
info = getRegionLocation(row); RegionLocation info = getRegionLocation(row);
HRegionInterface server = getHRegionConnection(info.serverAddress);
try { try {
values = getHRegionConnection(info.serverAddress). values = server.get(info.regionInfo.regionName, row, column, timestamp, numVersions);
get(info.regionInfo.regionName, row, column, timestamp, numVersions); break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
// No more tries // No more tries
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
findRegion(info); findRegion(info);
} }
try {
Thread.sleep(this.pause);
} catch (InterruptedException x) {
// continue
}
} }
if(values != null) { if(values != null) {
@ -1147,23 +1179,28 @@ public class HClient implements HConstants {
* @throws IOException * @throws IOException
*/ */
public SortedMap<Text, byte[]> getRow(Text row) throws IOException { public SortedMap<Text, byte[]> getRow(Text row) throws IOException {
RegionLocation info = null;
KeyedData[] value = null; KeyedData[] value = null;
for(int tries = 0; tries < numRetries; tries++) {
for(int tries = 0; tries < numRetries && info == null; tries++) { RegionLocation info = getRegionLocation(row);
info = getRegionLocation(row); HRegionInterface server = getHRegionConnection(info.serverAddress);
try { try {
value = getHRegionConnection(info.serverAddress).getRow( value = server.getRow(info.regionInfo.regionName, row);
info.regionInfo.regionName, row); break;
} catch(NotServingRegionException e) { } catch(NotServingRegionException e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
// No more tries // No more tries
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
findRegion(info); findRegion(info);
} }
try {
Thread.sleep(this.pause);
} catch (InterruptedException x) {
// continue
}
} }
TreeMap<Text, byte[]> results = new TreeMap<Text, byte[]>(); TreeMap<Text, byte[]> results = new TreeMap<Text, byte[]>();
if(value != null && value.length != 0) { if(value != null && value.length != 0) {
@ -1337,7 +1374,7 @@ public class HClient implements HConstants {
try { try {
this.currentServer.put(this.currentRegion, this.clientid, lockid, column, this.currentServer.put(this.currentRegion, this.clientid, lockid, column,
val); val);
} catch(IOException e) { } catch(Exception e) {
try { try {
this.currentServer.abort(this.currentRegion, this.clientid, lockid); this.currentServer.abort(this.currentRegion, this.clientid, lockid);
} catch(IOException e2) { } catch(IOException e2) {
@ -1345,7 +1382,7 @@ public class HClient implements HConstants {
} }
this.currentServer = null; this.currentServer = null;
this.currentRegion = null; this.currentRegion = null;
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -1360,7 +1397,7 @@ public class HClient implements HConstants {
try { try {
this.currentServer.delete(this.currentRegion, this.clientid, lockid, this.currentServer.delete(this.currentRegion, this.clientid, lockid,
column); column);
} catch(IOException e) { } catch(Exception e) {
try { try {
this.currentServer.abort(this.currentRegion, this.clientid, lockid); this.currentServer.abort(this.currentRegion, this.clientid, lockid);
} catch(IOException e2) { } catch(IOException e2) {
@ -1368,7 +1405,7 @@ public class HClient implements HConstants {
} }
this.currentServer = null; this.currentServer = null;
this.currentRegion = null; this.currentRegion = null;
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -1381,10 +1418,10 @@ public class HClient implements HConstants {
public void abort(long lockid) throws IOException { public void abort(long lockid) throws IOException {
try { try {
this.currentServer.abort(this.currentRegion, this.clientid, lockid); this.currentServer.abort(this.currentRegion, this.clientid, lockid);
} catch(IOException e) { } catch(Exception e) {
this.currentServer = null; this.currentServer = null;
this.currentRegion = null; this.currentRegion = null;
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -1410,9 +1447,10 @@ public class HClient implements HConstants {
this.currentServer.commit(this.currentRegion, this.clientid, lockid, this.currentServer.commit(this.currentRegion, this.clientid, lockid,
timestamp); timestamp);
} finally { } catch (Exception e) {
this.currentServer = null; this.currentServer = null;
this.currentRegion = null; this.currentRegion = null;
RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -1425,7 +1463,7 @@ public class HClient implements HConstants {
public void renewLease(long lockid) throws IOException { public void renewLease(long lockid) throws IOException {
try { try {
this.currentServer.renewLease(lockid, this.clientid); this.currentServer.renewLease(lockid, this.clientid);
} catch(IOException e) { } catch(Exception e) {
try { try {
this.currentServer.abort(this.currentRegion, this.clientid, lockid); this.currentServer.abort(this.currentRegion, this.clientid, lockid);
} catch(IOException e2) { } catch(IOException e2) {
@ -1433,7 +1471,7 @@ public class HClient implements HConstants {
} }
this.currentServer = null; this.currentServer = null;
this.currentRegion = null; this.currentRegion = null;
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
@ -1521,19 +1559,19 @@ public class HClient implements HConstants {
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
// No more tries // No more tries
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
findRegion(info); findRegion(info);
loadRegions(); loadRegions();
} }
} }
} catch(IOException e) { } catch(Exception e) {
close(); close();
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
return true; return true;
} }

View File

@ -1205,11 +1205,13 @@ public class HMaster implements HConstants, HMasterInterface,
try { try {
values = server.next(scannerId); values = server.next(scannerId);
} catch(NotServingRegionException e) { } catch(Exception e) {
throw e; try {
RemoteExceptionHandler.handleRemoteException(e);
} catch(IOException e) { } catch(Exception ex) {
LOG.error(e); LOG.error(ex);
}
break; break;
} }
@ -1405,9 +1407,9 @@ public class HMaster implements HConstants, HMasterInterface,
scanMetaRegion(server, scannerId, HGlobals.rootRegionInfo.regionName); scanMetaRegion(server, scannerId, HGlobals.rootRegionInfo.regionName);
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
} }
@ -1437,9 +1439,9 @@ public class HMaster implements HConstants, HMasterInterface,
} }
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
} }
@ -1536,9 +1538,9 @@ public class HMaster implements HConstants, HMasterInterface,
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
continue; continue;
} }
@ -1647,9 +1649,9 @@ public class HMaster implements HConstants, HMasterInterface,
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
pendingRegions.remove(regionName); pendingRegions.remove(regionName);
@ -1752,9 +1754,9 @@ public class HMaster implements HConstants, HMasterInterface,
assignAttempts.put(regionName, Long.valueOf(0L)); assignAttempts.put(regionName, Long.valueOf(0L));
break; break;
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
} }
} }
@ -1941,9 +1943,9 @@ public class HMaster implements HConstants, HMasterInterface,
} // for(MetaRegion m:) } // for(MetaRegion m:)
} // synchronized(metaScannerLock) } // synchronized(metaScannerLock)
} catch(NotServingRegionException e) { } catch(Exception e) {
if(tries == numRetries - 1) { if(tries == numRetries - 1) {
throw e; RemoteExceptionHandler.handleRemoteException(e);
} }
continue; continue;
} }
@ -2028,12 +2030,10 @@ public class HMaster implements HConstants, HMasterInterface,
LOG.debug("updated columns in row: " + i.regionName); LOG.debug("updated columns in row: " + i.regionName);
} }
} catch(NotServingRegionException e) { } catch(Exception e) {
throw e;
} catch(IOException e) {
LOG.error("column update failed in row: " + i.regionName); LOG.error("column update failed in row: " + i.regionName);
LOG.error(e); LOG.error(e);
RemoteExceptionHandler.handleRemoteException(e);
} finally { } finally {
try { try {
@ -2182,11 +2182,10 @@ public class HMaster implements HConstants, HMasterInterface,
if(LOG.isDebugEnabled()) { if(LOG.isDebugEnabled()) {
LOG.debug("updated columns in row: " + i.regionName); LOG.debug("updated columns in row: " + i.regionName);
} }
} catch(NotServingRegionException e) { } catch(Exception e) {
throw e;
} catch(IOException e) {
LOG.error("column update failed in row: " + i.regionName); LOG.error("column update failed in row: " + i.regionName);
LOG.error(e); LOG.error(e);
RemoteExceptionHandler.handleRemoteException(e);
} finally { } finally {
if(lockid != -1L) { if(lockid != -1L) {

View File

@ -0,0 +1,91 @@
/**
* Copyright 2007 The Apache Software Foundation
*
* Licensed 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.hbase;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.apache.hadoop.ipc.RemoteException;
/**
* An immutable class which contains a static method for handling
* org.apache.hadoop.ipc.RemoteException exceptions.
*/
public class RemoteExceptionHandler {
private RemoteExceptionHandler(){} // not instantiable
/**
* Converts org.apache.hadoop.ipc.RemoteException into original exception,
* if possible.
*
* @param e original exception
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static void handleRemoteException(final Exception e) throws IOException {
Exception ex = e;
if (e instanceof RemoteException) {
RemoteException r = (RemoteException) e;
Class c = null;
try {
c = Class.forName(r.getClassName());
} catch (ClassNotFoundException x) {
throw r;
}
Constructor ctor = null;
try {
Class[] parameterTypes = { String.class };
ctor = c.getConstructor(parameterTypes);
} catch (NoSuchMethodException x) {
throw r;
}
try {
Object[] arguments = { r.getMessage() };
ex = (Exception) ctor.newInstance(arguments);
} catch (IllegalAccessException x) {
throw r;
} catch (InvocationTargetException x) {
throw r;
} catch (InstantiationException x) {
throw r;
}
}
if (ex instanceof IOException) {
IOException io = (IOException) ex;
throw io;
} else if (ex instanceof RuntimeException) {
RuntimeException re = (RuntimeException) ex;
throw re;
} else {
AssertionError a = new AssertionError("unexpected exception");
a.initCause(ex);
throw a;
}
}
}