From 8ac8688f5c43a22d671c91397cdd5999139a4731 Mon Sep 17 00:00:00 2001 From: Tako Schotanus Date: Mon, 25 May 2026 20:37:28 +0200 Subject: [PATCH 1/3] test: added tests for #102 --- .../dev/jbang/devkitman/TestJdkManager.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/test/java/dev/jbang/devkitman/TestJdkManager.java b/src/test/java/dev/jbang/devkitman/TestJdkManager.java index f747d02..e2c820d 100644 --- a/src/test/java/dev/jbang/devkitman/TestJdkManager.java +++ b/src/test/java/dev/jbang/devkitman/TestJdkManager.java @@ -5,6 +5,8 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; @@ -83,6 +85,12 @@ void testDefault() { JdkManager jm = jdkManager(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(11), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(11).majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(12), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(12).majorVersion(), is(12)); + assertThat(jm.getDefaultJdkForVersion(13), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(13).majorVersion(), is(13)); jm.setDefaultJdk(Objects.requireNonNull(jm.getInstalledJdk("12"))); assertThat(jm.getDefaultJdk().majorVersion(), is(12)); assertThat(jm.getDefaultJdk().linked().id(), startsWith("12.0.7-distro-jbang")); @@ -94,6 +102,12 @@ void testDefaultPlus() { JdkManager jm = jdkManager(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(11), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(11).majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(14), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(14).majorVersion(), is(14)); + assertThat(jm.getDefaultJdkForVersion(17), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(17).majorVersion(), is(17)); jm.setDefaultJdk(Objects.requireNonNull(jm.getInstalledJdk("16+"))); assertThat(jm.getDefaultJdk().majorVersion(), is(17)); } @@ -194,9 +208,18 @@ void testDefaultUninstallNext() { JdkManager jm = jdkManager(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(14)); + assertThat(jm.getDefaultJdkForVersion(11), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(11).majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(14), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(14).majorVersion(), is(14)); + assertThat(jm.getDefaultJdkForVersion(17), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(17).majorVersion(), is(17)); + Jdk.LinkedJdk jdk14 = jm.getDefaultJdkForVersion(14); jm.getInstalledJdk("14", JdkProvider.Predicates.canInstall).uninstall(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(17)); + assertThat(jm.getDefaultJdkForVersion(14), nullValue()); + assertThat(Files.exists(jdk14.home(), LinkOption.NOFOLLOW_LINKS), is(false)); } @Test @@ -205,9 +228,17 @@ void testDefaultUninstallPrev() { JdkManager jm = jdkManager(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(17)); + assertThat(jm.getDefaultJdkForVersion(11), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(11).majorVersion(), is(11)); + assertThat(jm.getDefaultJdkForVersion(14), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(14).majorVersion(), is(14)); + assertThat(jm.getDefaultJdkForVersion(17), not(nullValue())); + assertThat(jm.getDefaultJdkForVersion(17).majorVersion(), is(17)); + Jdk.LinkedJdk jdk17 = jm.getDefaultJdkForVersion(17); jm.getInstalledJdk("17", JdkProvider.Predicates.canInstall).uninstall(); assertThat(jm.getDefaultJdk(), not(nullValue())); assertThat(jm.getDefaultJdk().majorVersion(), is(14)); + assertThat(Files.exists(jdk17.home(), LinkOption.NOFOLLOW_LINKS), is(false)); } @Test @@ -455,7 +486,9 @@ void testUninstallNumberLink() { assertThat(jdks.stream().map(Jdk::majorVersion).collect(Collectors.toList()), containsInAnyOrder(11, 11, 11)); assertThat(jdks.stream().map(Jdk::id).collect(Collectors.toList()), containsInAnyOrder("default", "12-default", "11-jbang")); - jdkManager().getOrInstallJdk("12", JdkProvider.Predicates.canUpdate).uninstall(); + Jdk.InstalledJdk jdk12 = jdkManager().getOrInstallJdk("12", JdkProvider.Predicates.canUpdate); + jdk12.uninstall(); + assertThat(Files.exists(jdk12.home(), LinkOption.NOFOLLOW_LINKS), is(false)); jdks = jdkManager().listInstalledJdks(); assertThat(jdks, hasSize(2)); assertThat(jdks.stream().map(Jdk::majorVersion).collect(Collectors.toList()), containsInAnyOrder(11, 11)); @@ -484,6 +517,9 @@ void testUninstallAll() { assertThat(jdks.stream().map(Jdk::id).collect(Collectors.toList()), containsInAnyOrder("default", "13-default", "13.0.7-distro-jbang")); jm.getOrInstallJdk("13", JdkProvider.Predicates.canInstall).uninstall(); + for (Jdk.InstalledJdk jdk : jdks) { + assertThat(Files.exists(jdk.home(), LinkOption.NOFOLLOW_LINKS), is(false)); + } jdks = jm.listInstalledJdks(); assertThat(jdks, empty()); } From 9594b9a920647e4b604425cdac5d3f0bb5d933e4 Mon Sep 17 00:00:00 2001 From: Tako Schotanus Date: Mon, 25 May 2026 20:37:50 +0200 Subject: [PATCH 2/3] chore: added some logging and comment fix --- src/main/java/dev/jbang/devkitman/JdkManager.java | 2 +- src/main/java/dev/jbang/devkitman/util/FileUtils.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/jbang/devkitman/JdkManager.java b/src/main/java/dev/jbang/devkitman/JdkManager.java index f3f05b5..1fedd71 100644 --- a/src/main/java/dev/jbang/devkitman/JdkManager.java +++ b/src/main/java/dev/jbang/devkitman/JdkManager.java @@ -478,7 +478,7 @@ void uninstallJdk(Jdk.@NonNull InstalledJdk jdk) { resetDefault = defHome.equals(jdk.home()); } } - // Check if the JDK is the global default JDK, if so we need to reset it + // Check if the JDK is the version default JDK, if so we need to reset it Jdk.InstalledJdk defaultJdkVer = getDefaultJdk(); if (defaultJdkVer != null) { Path defHome = defaultJdkVer.home(); diff --git a/src/main/java/dev/jbang/devkitman/util/FileUtils.java b/src/main/java/dev/jbang/devkitman/util/FileUtils.java index 9938a8f..c9618c3 100644 --- a/src/main/java/dev/jbang/devkitman/util/FileUtils.java +++ b/src/main/java/dev/jbang/devkitman/util/FileUtils.java @@ -15,10 +15,12 @@ public static void createLink(Path link, Path target) { // creation doesn't require any special privileges. if (OsUtils.isWindows() && Files.isDirectory(target)) { if (createJunction(link, target.toAbsolutePath())) { + LOGGER.log(Level.FINE, "Created link (junction) {0}", target); return; } } else { if (createSymbolicLink(link, target.toAbsolutePath())) { + LOGGER.log(Level.FINE, "Created link (symbolic) {0}", target); return; } } From 9f30c12bd85a6a02a4ae8c3d07c856e9c9b0b1c2 Mon Sep 17 00:00:00 2001 From: Tako Schotanus Date: Tue, 26 May 2026 09:56:30 +0200 Subject: [PATCH 3/3] fix: dangling default links get properly removed Fixes #102 --- .../java/dev/jbang/devkitman/JdkManager.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/dev/jbang/devkitman/JdkManager.java b/src/main/java/dev/jbang/devkitman/JdkManager.java index 1fedd71..85157d7 100644 --- a/src/main/java/dev/jbang/devkitman/JdkManager.java +++ b/src/main/java/dev/jbang/devkitman/JdkManager.java @@ -464,36 +464,44 @@ private Jdk getJdkByVersion( } void uninstallJdk(Jdk.@NonNull InstalledJdk jdk) { - boolean resetDefault = false; - boolean resetDefaultVer = false; + Jdk.InstalledJdk resetDefault = null; + Jdk.InstalledJdk resetDefaultVer = null; if (hasDefaultProvider() && !jdk.provider().equals(defaultProvider)) { // Check if the JDK is the global default JDK, if so we need to reset it Jdk.InstalledJdk defaultJdk = getDefaultJdk(); if (defaultJdk != null) { + boolean reset; Path defHome = defaultJdk.home(); try { - resetDefault = Files.isSameFile(defHome, jdk.home()); + reset = Files.isSameFile(defHome, jdk.home()); } catch (IOException ex) { LOGGER.log(Level.WARNING, "Error while trying to reset global default JDK", ex); - resetDefault = defHome.equals(jdk.home()); + reset = defHome.equals(jdk.home()); + } + if (reset) { + resetDefault = defaultJdk; } } // Check if the JDK is the version default JDK, if so we need to reset it - Jdk.InstalledJdk defaultJdkVer = getDefaultJdk(); + Jdk.InstalledJdk defaultJdkVer = getDefaultJdkForVersion(jdk.majorVersion()); if (defaultJdkVer != null) { + boolean reset; Path defHome = defaultJdkVer.home(); try { - resetDefaultVer = Files.isSameFile(defHome, jdk.home()); + reset = Files.isSameFile(defHome, jdk.home()); } catch (IOException ex) { LOGGER.log(Level.WARNING, "Error while trying to reset versioned default JDK", ex); - resetDefaultVer = defHome.equals(jdk.home()); + reset = defHome.equals(jdk.home()); + } + if (reset) { + resetDefaultVer = defaultJdkVer; } } } jdk.provider().uninstall(jdk); - if (resetDefault) { + if (resetDefault != null) { Optional newjdk = nextInstalledJdk(Jdk.Predicates.minVersion(jdk.majorVersion()), JdkProvider.Predicates.canInstall); if (!newjdk.isPresent()) { @@ -503,11 +511,11 @@ void uninstallJdk(Jdk.@NonNull InstalledJdk jdk) { if (newjdk.isPresent()) { setDefaultJdk(newjdk.get()); } else { - removeDefaultJdk(); + resetDefault.uninstall(); LOGGER.log(Level.INFO, "Global default JDK unset"); } } - if (resetDefaultVer) { + if (resetDefaultVer != null) { int v = jdk.majorVersion(); Optional newjdk = nextInstalledJdk(Jdk.Predicates.exactVersion(v), JdkProvider.Predicates.canInstall); @@ -517,7 +525,7 @@ void uninstallJdk(Jdk.@NonNull InstalledJdk jdk) { if (newjdk.isPresent()) { setDefaultJdkForVersion(newjdk.get()); } else { - removeDefaultJdkForVersion(v); + resetDefaultVer.uninstall(); LOGGER.log(Level.INFO, "Versioned default JDK unset"); } }