code: public <T extends Writable> T readWritableFromZk(
        String fullyQualifiedPath, T writable, Stat stat) throws IOException {
      try {
        byte[] data = zooKeeper.getData(fullyQualifiedPath, false, stat);
        if (data == null) {
          LOG.fatal("ZNode " + fullyQualifiedPath + " has no ledger metadata!");
          throw new IOException("ZNode " + fullyQualifiedPath +
              " has no ledger metadata!");
        }
        return WritableUtil.readWritableFromByteArray(data, writable);
      } catch (InterruptedException e) {
        interruptedException("Interrupted reading from " +
            fullyQualifiedPath, e);
        return null; // Should not be reached
      } catch (KeeperException.NoNodeException e) {
        LOG.warn("ZNode " + fullyQualifiedPath +
            " does not exist, returning null! Not re-throwing " + e);
        return null;
      } catch (KeeperException e) {
        keeperException("Unrecoverable ZooKeeper error reading from " +
            fullyQualifiedPath, e);
        return null;
      }
    }
docs: Read a {@link Writable} from a specified ZNode path ZooKeeper and
  (optionally) update its {@link Stat} information (if supplied).
  The ZNode must either not exist or contain a valid writable: an empty
  ZNode will result in an IllegalArgumentException being thrown.
  @param fullyQualifiedPath Full path to the ZNode containing the writable
  @param writable A newly instantiated instance of the writable. Must not
  be null.
  @param stat The stat object for ZNode stats or null if none desired.
  @param <T> Type of the writable (must implement Writable)
  @return The updated writable instance or null if the specified path does
  not exist
  @throws IOException If there is an unrecoverable error communicating to
  ZooKeeper
  @throws IllegalArgumentException If the data contained in the specified
  ZNode is null