public LocalResource localizeResource(
      Path src, Path dest, LocalResourceType type, Configuration conf) throws IOException {
    FileSystem destFS = dest.getFileSystem(conf);
    FileSystem srcFs;
    if (src.toUri().getScheme() != null) {
      srcFs = src.getFileSystem(conf);
    } else {
      srcFs = FileSystem.getLocal(conf);
    }

    if (!checkPreExisting(srcFs, src, dest, conf)) {
      // copy the src to the destination and create local resource.
      // do not overwrite.
      String srcStr = src.toString();
      LOG.info("Localizing resource because it does not exist: " + srcStr + " to dest: " + dest);
      Object notifierNew = new Object(),
          notifierOld = copyNotifiers.putIfAbsent(srcStr, notifierNew),
          notifier = (notifierOld == null) ? notifierNew : notifierOld;
      // To avoid timing issues with notifications (and given that HDFS check is anyway the
      // authoritative one), don't wait infinitely for the notifier, just wait a little bit
      // and check HDFS before and after.
      if (notifierOld != null
          && checkOrWaitForTheFile(srcFs, src, dest, conf, notifierOld, 1, 150, false)) {
        return createLocalResource(destFS, dest, type, LocalResourceVisibility.PRIVATE);
      }
      try {
        // FileUtil.copy takes care of copy from local filesystem internally.
        FileUtil.copy(srcFs, src, destFS, dest, false, false, conf);
        synchronized (notifier) {
          notifier.notifyAll(); // Notify if we have successfully copied the file.
        }
        copyNotifiers.remove(srcStr, notifier);
      } catch (IOException e) {
        if ("Exception while contacting value generator".equals(e.getMessage())) {
          // HADOOP-13155, fixed version: 2.8.0, 3.0.0-alpha1
          throw new IOException("copyFromLocalFile failed due to HDFS KMS failure", e);
        }

        LOG.info("Looks like another thread or process is writing the same file");
        int waitAttempts = HiveConf.getIntVar(
            conf, ConfVars.HIVE_LOCALIZE_RESOURCE_NUM_WAIT_ATTEMPTS);
        long sleepInterval = HiveConf.getTimeVar(
            conf, HiveConf.ConfVars.HIVE_LOCALIZE_RESOURCE_WAIT_INTERVAL, TimeUnit.MILLISECONDS);
        // Only log on the first wait, and check after wait on the last iteration.
        if (!checkOrWaitForTheFile(
            srcFs, src, dest, conf, notifierOld, waitAttempts, sleepInterval, true)) {
          LOG.error("Could not find the jar that was being uploaded: src = {}, dest = {}, type = {}", src, dest, type);
          throw new IOException("Could not find jar while attempting to localize resource. Previous writer may have " +
              "failed to write " + dest + ". Failing because I am unlikely to write too. Refer to exception for more " +
              "troubleshooting details.", e);
        }
      } finally {
        if (notifier == notifierNew) {
          copyNotifiers.remove(srcStr, notifierNew);
        }
      }
    }
    return createLocalResource(destFS, dest, type, LocalResourceVisibility.PRIVATE);
  }
Localizes a resources. Should be thread-safe.
@param src path to the source for the resource
@param dest path in hdfs for the resource
@param type local resource type (File/Archive)
@param conf
@return localresource from tez localization.
@throws IOException when any file system related calls fails.
ql/src/java/org/apache/hadoop/hive/ql/exec/tez/DagUtils.java