@VisibleForTesting
  boolean checkSymlink(File jar) {
    if (Files.isSymbolicLink(jar.toPath())) {
      try {
        java.nio.file.Path link = Files.readSymbolicLink(jar.toPath());
        java.nio.file.Path jarPath = Paths.get(jar.getAbsolutePath());
        String linkString = link.toString();
        java.nio.file.Path jarParent = jarPath.getParent();
        java.nio.file.Path linkPath =
            jarParent == null ? null : jarParent.resolve(linkString);
        java.nio.file.Path linkPathParent =
            linkPath == null ? null : linkPath.getParent();
        java.nio.file.Path normalizedLinkPath =
            linkPathParent == null ? null : linkPathParent.normalize();
        if (normalizedLinkPath != null && jarParent.normalize().equals(
            normalizedLinkPath)) {
          LOG.info(String.format("Ignoring same directory link %s to %s",
              jarPath.toString(), link.toString()));
          return true;
        }
      } catch (NotLinkException ex) {
        LOG.debug("Not a link", jar);
      } catch (IOException ex) {
        LOG.warn("Cannot read symbolic link on", jar);
      }
    }
    return false;
  }
@Test
  void testNativeIO() throws IOException {
    FrameworkUploader uploader = new FrameworkUploader();
    File parent = new File(testDir);
    try {
      // Create a parent directory
      parent.deleteOnExit();
      assertTrue(parent.mkdirs());

      // Create a target file
      File targetFile = new File(parent, "a.txt");
      try (FileOutputStream os = new FileOutputStream(targetFile)) {
        IOUtils.writeLines(Lists.newArrayList("a", "b"), null, os, StandardCharsets.UTF_8);
      }
      assertFalse(uploader.checkSymlink(targetFile));

      // Create a symlink to the target
      File symlinkToTarget = new File(parent, "symlinkToTarget.txt");
      try {
        Files.createSymbolicLink(
            Paths.get(symlinkToTarget.getAbsolutePath()),
            Paths.get(targetFile.getAbsolutePath()));
      } catch (UnsupportedOperationException e) {
        // Symlinks are not supported, so ignore the test
        Assumptions.assumeTrue(false);
      }
      assertTrue(uploader.checkSymlink(symlinkToTarget));

      // Create a symlink to the target with /./ in the path
      symlinkToTarget = new File(parent.getAbsolutePath() +
          "/./symlinkToTarget2.txt");
      try {
        Files.createSymbolicLink(
            Paths.get(symlinkToTarget.getAbsolutePath()),
            Paths.get(targetFile.getAbsolutePath()));
      } catch (UnsupportedOperationException e) {
        // Symlinks are not supported, so ignore the test
        Assumptions.assumeTrue(false);
      }
      assertTrue(uploader.checkSymlink(symlinkToTarget));

      // Create a symlink outside the current directory
      File symlinkOutside = new File(parent, "symlinkToParent.txt");
      try {
        Files.createSymbolicLink(
            Paths.get(symlinkOutside.getAbsolutePath()),
            Paths.get(parent.getAbsolutePath()));
      } catch (UnsupportedOperationException e) {
        // Symlinks are not supported, so ignore the test
        Assumptions.assumeTrue(false);
      }
      assertFalse(uploader.checkSymlink(symlinkOutside));
    } finally {
      FileUtils.forceDelete(parent);
    }

  }