code: public static <V, E extends Exception> V getFutureValue(Future<V> future, Class<E> exceptionType)
              throws E
      {
          requireNonNull(future, "future is null");
          requireNonNull(exceptionType, "exceptionType is null");
  
          try {
              return future.get();
          }
          catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              throw new RuntimeException("interrupted", e);
          }
          catch (ExecutionException e) {
              Throwable cause = e.getCause() == null ? e : e.getCause();
              propagateIfPossible(cause, exceptionType);
              throw new RuntimeException(cause);
          }
      }
docs: Waits for the value from the future. If the future is failed, the exception
  is thrown directly if it is an instance of the specified exception type or
  unchecked, or it is wrapped in a RuntimeException. If the thread is
  interrupted, the thread interruption flag is set and the original
  InterruptedException is wrapped in a RuntimeException and thrown.