import java.io.IOException;
import java.nio.file.FileSystemLoopException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Set;

public class TestSymlink {
    public static void main(String[] args) throws IOException {
        Path tempDir = Files.createTempDirectory("testdir");
        tempDir.toFile().deleteOnExit();
        Path symbolicLink = Files.createSymbolicLink(tempDir.resolve("mysymlink"), tempDir);
        symbolicLink.toFile().deleteOnExit();
        Files.walkFileTree(symbolicLink, Set.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
                new SimpleFileVisitor<java.nio.file.Path>() {
                    public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) {
                        if (dir.equals(symbolicLink)) {
                            System.out.println("attrs.isSymbolicLink:" + attrs.isSymbolicLink()
                                    + " Files.isSymbolicLink: " + Files.isSymbolicLink(dir));
                            return FileVisitResult.SKIP_SUBTREE;
                        }
                        return FileVisitResult.CONTINUE;

                    }

                });
        Files.walkFileTree(tempDir, Set.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
                new SimpleFileVisitor<java.nio.file.Path>() {
                    @Override
                    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                        if (exc instanceof FileSystemLoopException) {
                            System.out.println("cycle detected (expected): " + file);
                            return FileVisitResult.CONTINUE;
                        }
                        throw exc;
                    }
                });
    }
}
