code: public static boolean rename(FileSystem fs, Path from, Path to)
    {
      try {
        // Note: Using reflection instead of simpler
        // fs.rename(from, to, Options.Rename.NONE);
        // due to the issues discussed in https://github.com/apache/incubator-druid/pull/3787
        Method renameMethod = findRenameMethodRecursively(fs.getClass());
        renameMethod.invoke(fs, from, to, new Options.Rename[]{Options.Rename.NONE});
        return true;
      }
      catch (InvocationTargetException ex) {
        if (ex.getTargetException() instanceof FileAlreadyExistsException) {
          log.info(ex, "Destination exists while renaming [%s] to [%s]", from, to);
          return false;
        } else {
          throw new RuntimeException(ex);
        }
      }
      catch (NoSuchMethodException | IllegalAccessException ex) {
  
        for (Method method : fs.getClass().getDeclaredMethods()) {
          log.error(method.toGenericString());
        }
        throw new RuntimeException(ex);
      }
    }
docs: Same as FileSystem.rename(from, to, Options.Rename). It is different from FileSystem.rename(from, to) which moves
  "from" directory inside "to" directory if it already exists.
  
  @param from
  @param to
  
  @return true if operation succeeded, false if destination already exists
  
  @throws IOException if trying to overwrite a non-empty directory