From b316530267c25bed51e361285c17601bc47c97be Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Mon, 12 Jan 2026 15:35:01 +0100 Subject: [PATCH] Simplify SymLink creation in eclipse.core.tests Co-authored-by: Luise Ravnskjaer <13628062+ravnskjaer@users.noreply.github.com> --- .../core/tests/harness/FileSystemHelper.java | 65 ++++--------------- 1 file changed, 14 insertions(+), 51 deletions(-) diff --git a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java index f5b58a10d55..9270355313f 100644 --- a/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java +++ b/runtime/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java @@ -17,10 +17,9 @@ import static org.eclipse.core.tests.harness.TestHarnessPlugin.PI_HARNESS; import static org.eclipse.core.tests.harness.TestHarnessPlugin.log; -import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; +import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.Path; import java.util.concurrent.Callable; @@ -109,60 +108,23 @@ public static void clear(java.io.File file) { /** * Creates a symbolic link. Should only be called on platforms where symbolic - * links can actually be created, i.e. an "ln" command is available. + * links can actually be created, i.e. an "ln" command is available respectively + * if {@link #canCreateSymLinks()} returns {@code true}. * * @param basedir folder in which the symbolic link should be created * @param linkName name of the symbolic link * @param linkTarget target to which the symbolic link should point - * @param isDir true if the link should point to a folder - * @throws IllegalStateException in case symlink creation is not supported - * @throws IOException in case the creation of the symlink failed for - * other reasons + * @param isDir unused, retained for compatibility + * @throws FileSystemException if the link could not be created, e.g. + * due to missing privileges on Windows + * @throws UnsupportedOperationException if symbolic links are generally not + * supported on the current platform + * @throws IOException in case the creation of the symlink + * failed for other reasons */ public static void createSymLink(File basedir, String linkName, String linkTarget, boolean isDir) throws IOException { - // The following code creates even a link if - // Files.createSymbolicLink(new File(basedir, linkName).toPath(), new - // File(basedir, linkTarget).toPath()); - // would throw java.nio.file.FileSystemException "missing rights" - // - Process process = startSymlinkCreation(basedir, linkName, linkTarget, isDir); - try { - int exitcode = process.waitFor(); - if (exitcode != 0) { - // xxx wrong charset. from jdk17+ we could use Console.charset() - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String result = reader.readLine(); - throw new IllegalStateException("Creating symlink is unsupported: " + result); - } - } - } catch (InterruptedException e) { - throw new IOException("Creating symlink failed due to interrupted exception", e); - } - } - - private static Process startSymlinkCreation(File basedir, String linkName, String linkTarget, boolean isDir) - throws IOException { - // Deliberately use an empty environment to make the test reproducible. - String[] environmentParameters = {}; - if (Platform.getOS().equals(Platform.OS_WIN32)) { - return startSymlinkCreationOnWindows(basedir, linkName, linkTarget, isDir, environmentParameters); - } - String[] cmd = { "ln", "-s", linkTarget, linkName }; - return Runtime.getRuntime().exec(cmd, environmentParameters, basedir); - } - - private static Process startSymlinkCreationOnWindows(File basedir, String linkName, String linkTarget, - boolean isDir, String[] environmentParameters) throws IOException { - // use File.getPath to avoid 'Illegal argument - ".."' for using "../" - // instead of "..\" - if (isDir) { - String[] cmd = { "cmd", "/c", "mklink", "/d", new File(linkName).getPath(), - new File(linkTarget).getPath() }; - return Runtime.getRuntime().exec(cmd, environmentParameters, basedir); - } - String[] cmd = { "cmd", "/c", "mklink", new File(linkName).getPath(), new File(linkTarget).getPath() }; - return Runtime.getRuntime().exec(cmd, environmentParameters, basedir); + Files.createSymbolicLink(basedir.toPath().resolve(linkName), Path.of(linkTarget)); } /** @@ -185,8 +147,9 @@ public static boolean canCreateSymLinks() throws IOException { // Clean up if the link was created. new File(tempDir.toFile(), linkName).delete(); canCreateSymLinks = Boolean.TRUE; - } catch (IllegalStateException e) { - // This exception indicates that creation of the symlink failed. + } catch (FileSystemException | UnsupportedOperationException e) { + // Creating the symlink failed, e.g. due to missing privileges or because + // symlinks are generally not supported on the current platform. canCreateSymLinks = Boolean.FALSE; } } else {