@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      Deadline.registerIfNot(socketTimeout);
      boolean isTimerStarted = Deadline.startTimer(method.getName());
      try {
        return method.invoke(base, args);
      } finally {
        if (isTimerStarted) {
          Deadline.stopTimer();
        }
      }
    } catch (UndeclaredThrowableException e) {
      throw e.getCause();
    } catch (InvocationTargetException e) {
      throw e.getCause();
    }
  }
@Test
  public void testExceptionDispatch() throws Throwable {
    Configuration conf = MetastoreConf.newMetastoreConf();
    MetastoreConf.setTimeVar(conf, MetastoreConf.ConfVars.CLIENT_SOCKET_TIMEOUT, 10,
        TimeUnit.MILLISECONDS);
    RawStoreProxy rsp = new RawStoreProxy(conf, conf, TestStore.class);
    try {
      rsp.invoke(null, TestStore.class.getMethod("exceptions"), new Object[] {});
      fail("an exception is expected");
    } catch (IllegalStateException ise) {
      // expected
    }
    Thread.sleep(20);
    // this shouldn't throw an exception
    rsp.invoke(null, TestStore.class.getMethod("noopMethod"), new Object[] {});
  }