code: private static BufferedReader getTaskLogReader(final URL taskLogUrl)
        throws IOException {
      FutureTask<BufferedReader> task = new FutureTask<BufferedReader>(
          new Callable<BufferedReader>() {
            @Override
            public BufferedReader call() throws IOException {
              URLConnection connection = taskLogUrl.openConnection();
              BufferedReader input = new BufferedReader(
                  new InputStreamReader(connection.getInputStream()));
              return input;
            }
          });
      Thread thread = new Thread(task);
      thread.setDaemon(true);
      thread.start();
      BufferedReader result = null;
      try {
        // Fails if we cannot open the input stream for 5 minutes.
        // This prevents JobClient from hanging
        result = task.get(5, TimeUnit.MINUTES);
      } catch (InterruptedException e) {
        throw new IOException(e);
      } catch (TimeoutException e) {
        throw new IOException(e);
      } catch (ExecutionException e) {
        throw new IOException(e);
      }
      if (result == null) {
        throw new IOException("Failed to open input stream for " + taskLogUrl);
      }
      return result;
    }
docs: Get a {@link BufferedReader} to read the taskLog by lines.
  @param taskLogUrl The URL of the taskLog location
  @return A {@link BufferedReader} to read the taskLog by lines
  @throws IOException Will throw this if we cannot get the reader for 5 mins