From 69b960e9257f4c72479ac1023fa901bd9627ab1c Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sat, 14 Dec 2024 05:22:46 +0800 Subject: [PATCH 01/11] Update i18n field "java.add.failed.some" --- HMCL/src/main/resources/assets/lang/I18N.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_es.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_ja.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_ru.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_zh.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties | 1 + 6 files changed, 6 insertions(+) diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 79f5b8394b..11e3c2b55b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -705,6 +705,7 @@ install.success=Successfully installed. java.add=Add Java java.add.failed=This Java is invalid or incompatible with the current platform. +java.add.failed.some=Some of the found Java is invalid or incompatible with the current platform. java.disable=Disable Java java.disable.confirm=Are you sure you want to disable this Java? java.disabled.management=Disabled Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 20122a125d..3374db9dc1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -600,6 +600,7 @@ install.success=Instalado con éxito. java.add=Añadir Java java.add.failed=Este Java no es válido o es incompatible con la plataforma actual. +java.add.failed.some=Parte del Java encontrado no es válido o es incompatible con la plataforma actual. java.disable=Deshabilitar este Java java.disable.confirm=¿Está seguro de que desea desactivar este Java? java.disabled.management=Java desactivado diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index 170d0c691f..a93a54c176 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -462,6 +462,7 @@ install.success=正常にインストールされました java.add=Javaの追加 java.add.failed=このJavaは無効であるか、現在のプラットフォームと互換性がない。 +java.add.failed.some=見つかったJavaのいくつかは無効であるか、現在のプラットフォームと互換性がありません。 java.disable=無効化 java.disable.confirm=本当にこのJavaを無効にしますか? java.disabled.management=無効なJava diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 15f88033d9..6e6e513e41 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -480,6 +480,7 @@ install.success=Успешно установлено. java.add=Добавить Java java.add.failed=Этот Java недопустим или несовместим с текущей платформой. +java.add.failed.some=Некоторые из найденных Java недопустимы или несовместимы с текущей платформой. java.disable=Отключить Java java.disable.confirm=Вы уверены, что хотите отключить эту Java? java.disabled.management=Отключенная Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 4058fadbfb..a0308b4212 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -519,6 +519,7 @@ install.success=安裝成功 java.add=添加 Java java.add.failed=Java 無效或與目前平臺不相容 +java.add.failed.some=找到的某些 Java 無效或與目前平臺不相容 java.disable=禁用此 Java java.disable.confirm=你確定要禁用此 Java 嗎? java.disabled.management=管理已禁用的 Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index a521d602fd..12f9c78583 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -530,6 +530,7 @@ install.success=安装成功 java.add=添加 Java java.add.failed=Java 无效或与当前平台不兼容。 +java.add.failed.some=找到的部分 Java 无效或与当前平台不兼容。 java.disable=禁用此 Java java.disable.confirm=你确定要禁用此 Java 吗? java.disabled.management=管理已禁用的 Java From bbcf928853d753c82de711d49fd86d82dcd3d2eb Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sat, 14 Dec 2024 05:23:09 +0800 Subject: [PATCH 02/11] Change action of "Add Java" to search Java in the directory, optimized code --- .../org/jackhuang/hmcl/java/JavaManager.java | 72 +++++++++++++++++++ .../hmcl/ui/main/JavaManagementPage.java | 33 +++++---- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index a5592e6a9b..38e33a531f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -41,6 +41,7 @@ import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.nio.file.*; @@ -176,6 +177,77 @@ public static void refresh() { }).start(); } + private static class SearchJavaTask extends Task> { + + private final File directory; + + SearchJavaTask(File directory, String name) { + this.directory = directory; + setName(name); + } + + @Override + public void execute() throws Exception { + setResult(searchJava()); + } + + private List searchJava() throws IOException, InterruptedException { + final int maxDepth = 2; + + Queue fileQueue = new ArrayDeque<>(64); + ArrayList binaryList = new ArrayList<>(); + final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); + File[] subDirs = directory.listFiles(File::isDirectory); + if(subDirs == null) return binaryList; + fileQueue.addAll(Arrays.asList(subDirs)); + fileQueue.add(directory); + int depth = 0; + while (depth < maxDepth) { + if(isCancelled()) + return Collections.emptyList(); + if(fileQueue.isEmpty()) break; + final File dir = fileQueue.poll(); + if (dir == directory) { + depth++; + if (!fileQueue.isEmpty() && depth < maxDepth - 1) + fileQueue.add(directory); + continue; + } + final File binary = new File(dir, relative); + if (binary.exists()) { + binaryList.add(JavaManager.getJava(binary.toPath())); + continue; + } + subDirs = dir.listFiles(File::isDirectory); + if (subDirs != null) + fileQueue.addAll(Arrays.asList(subDirs)); + } + return binaryList; + } + } + + public static Task> getSearchAndAddJavaTask(File directory) { + return new SearchJavaTask(directory, "Search Java") + .thenApplyAsync("Add Java", Schedulers.javafx(), javaRuntimes -> { + ArrayList failedJavaRuntimes = new ArrayList<>(); + for(JavaRuntime javaRuntime: javaRuntimes) { + if(!JavaManager.isCompatible(javaRuntime.getPlatform())) + failedJavaRuntimes.add(javaRuntime); + String pathString = javaRuntime.getBinary().toString(); + ConfigHolder.globalConfig().getDisabledJava().remove(pathString); + if(ConfigHolder.globalConfig().getUserJava().add(pathString)) + addJava(javaRuntime); + } + if(!failedJavaRuntimes.isEmpty()) { + StringBuilder sb = new StringBuilder("Incompatible platform: "); + for(JavaRuntime javaRuntime :javaRuntimes) + sb.append('\n').append(javaRuntime.getPlatform()).append(": ").append(javaRuntime.getBinary()); + throw new UnsupportedPlatformException(sb.toString()); + } + return javaRuntimes; + }); + } + public static Task getAddJavaTask(Path binary) { return Task.supplyAsync("Get Java", () -> JavaManager.getJava(binary)) .thenApplyAsync(Schedulers.javafx(), javaRuntime -> { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index 6eb9c2d450..60cfa0e8a2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -29,7 +29,7 @@ import javafx.scene.control.SkinBase; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; -import javafx.stage.FileChooser; +import javafx.stage.DirectoryChooser; import org.jackhuang.hmcl.java.JavaInfo; import org.jackhuang.hmcl.java.JavaManager; import org.jackhuang.hmcl.java.JavaRuntime; @@ -106,25 +106,34 @@ protected Skin createDefaultSkin() { } void onAddJava() { - FileChooser chooser = new FileChooser(); - if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) - chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Java", "java.exe")); + final DirectoryChooser chooser = new DirectoryChooser(); chooser.setTitle(i18n("settings.game.java_directory.choose")); - File file = chooser.showOpenDialog(Controllers.getStage()); - if (file != null) { - JavaManager.getAddJavaTask(file.toPath()).whenComplete(Schedulers.javafx(), exception -> { - if (exception != null) { - LOG.warning("Failed to add java", exception); - Controllers.dialog(i18n("java.add.failed"), i18n("message.error"), MessageDialogPane.MessageType.ERROR); - } - }).start(); + File directory = chooser.showDialog(Controllers.getStage()); + if(directory == null) return; + + final File file = new File(directory, OperatingSystem.CURRENT_OS.getJavaExecutable()); + if(file.exists()) { + onAddJavaBinary(file.toPath()); + return; } + + onSearchAndAddJavaBinary(directory); } void onShowRestoreJavaPage() { Controllers.navigate(new JavaRestorePage(ConfigHolder.globalConfig().getDisabledJava())); } + private void onSearchAndAddJavaBinary(File directory) { + Task task = JavaManager.getSearchAndAddJavaTask(directory).whenComplete(Schedulers.javafx(), exception -> { + if (exception instanceof UnsupportedPlatformException) { + LOG.warning("Failed to add java", exception); + Controllers.dialog(i18n("java.add.failed.some"), i18n("message.error"), MessageDialogPane.MessageType.ERROR); + } else LOG.warning("Other exception when add java", exception); + }); + Controllers.taskDialog(task, i18n("java.add"), TaskCancellationAction.NORMAL); + } + private void onAddJavaBinary(Path file) { JavaManager.getAddJavaTask(file).whenComplete(Schedulers.javafx(), exception -> { if (exception != null) { From cd9fe39ddcb67b6a2cfca2e8ba2b669c12fe264d Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sun, 15 Dec 2024 18:58:58 +0800 Subject: [PATCH 03/11] Fix cannot limit recursion level & some optimize --- .../org/jackhuang/hmcl/java/JavaManager.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index 38e33a531f..80838ac5f2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -192,20 +192,16 @@ public void execute() throws Exception { } private List searchJava() throws IOException, InterruptedException { - final int maxDepth = 2; + final int maxDepth = 3; - Queue fileQueue = new ArrayDeque<>(64); - ArrayList binaryList = new ArrayList<>(); - final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); File[] subDirs = directory.listFiles(File::isDirectory); - if(subDirs == null) return binaryList; - fileQueue.addAll(Arrays.asList(subDirs)); + if(subDirs == null) return Collections.emptyList(); + List binaryList = new ArrayList<>(); + Queue fileQueue = new LinkedList<>(Arrays.asList(subDirs)); fileQueue.add(directory); + final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); int depth = 0; - while (depth < maxDepth) { - if(isCancelled()) - return Collections.emptyList(); - if(fileQueue.isEmpty()) break; + while(!fileQueue.isEmpty()) { final File dir = fileQueue.poll(); if (dir == directory) { depth++; @@ -218,11 +214,15 @@ private List searchJava() throws IOException, InterruptedException binaryList.add(JavaManager.getJava(binary.toPath())); continue; } - subDirs = dir.listFiles(File::isDirectory); - if (subDirs != null) - fileQueue.addAll(Arrays.asList(subDirs)); + if(depth < maxDepth - 1) { + subDirs = dir.listFiles(File::isDirectory); + if (subDirs != null) + fileQueue.addAll(Arrays.asList(subDirs)); + } + if(isCancelled()) + return Collections.emptyList(); } - return binaryList; + return Collections.unmodifiableList(binaryList); } } From 279f6d12989a2ea788710d47632544c98cb83d7f Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sun, 15 Dec 2024 19:16:55 +0800 Subject: [PATCH 04/11] Loop optimize --- HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index 80838ac5f2..f18acc38af 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -200,12 +200,12 @@ private List searchJava() throws IOException, InterruptedException Queue fileQueue = new LinkedList<>(Arrays.asList(subDirs)); fileQueue.add(directory); final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); - int depth = 0; + int depth = 1; while(!fileQueue.isEmpty()) { final File dir = fileQueue.poll(); if (dir == directory) { depth++; - if (!fileQueue.isEmpty() && depth < maxDepth - 1) + if (!fileQueue.isEmpty() && depth < maxDepth) fileQueue.add(directory); continue; } @@ -214,7 +214,7 @@ private List searchJava() throws IOException, InterruptedException binaryList.add(JavaManager.getJava(binary.toPath())); continue; } - if(depth < maxDepth - 1) { + if(depth < maxDepth) { subDirs = dir.listFiles(File::isDirectory); if (subDirs != null) fileQueue.addAll(Arrays.asList(subDirs)); From 6fb38ce25fba35b17b6313187153c2c4c3b6fbde Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sun, 15 Dec 2024 19:55:30 +0800 Subject: [PATCH 05/11] Update i18n field "java.add.not_found" --- HMCL/src/main/resources/assets/lang/I18N.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_es.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_ja.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_ru.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_zh.properties | 1 + HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties | 1 + 6 files changed, 6 insertions(+) diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 11e3c2b55b..4122eb918a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -706,6 +706,7 @@ install.success=Successfully installed. java.add=Add Java java.add.failed=This Java is invalid or incompatible with the current platform. java.add.failed.some=Some of the found Java is invalid or incompatible with the current platform. +java.add.not_found=Java not found in specified directory, or the Java directory is too deep. java.disable=Disable Java java.disable.confirm=Are you sure you want to disable this Java? java.disabled.management=Disabled Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_es.properties b/HMCL/src/main/resources/assets/lang/I18N_es.properties index 3374db9dc1..812d7ef21a 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_es.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_es.properties @@ -601,6 +601,7 @@ install.success=Instalado con éxito. java.add=Añadir Java java.add.failed=Este Java no es válido o es incompatible con la plataforma actual. java.add.failed.some=Parte del Java encontrado no es válido o es incompatible con la plataforma actual. +java.add.not_found=Java no se encuentra en el directorio especificado, o el directorio Java es demasiado profundo. java.disable=Deshabilitar este Java java.disable.confirm=¿Está seguro de que desea desactivar este Java? java.disabled.management=Java desactivado diff --git a/HMCL/src/main/resources/assets/lang/I18N_ja.properties b/HMCL/src/main/resources/assets/lang/I18N_ja.properties index a93a54c176..ecbc27002e 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ja.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ja.properties @@ -463,6 +463,7 @@ install.success=正常にインストールされました java.add=Javaの追加 java.add.failed=このJavaは無効であるか、現在のプラットフォームと互換性がない。 java.add.failed.some=見つかったJavaのいくつかは無効であるか、現在のプラットフォームと互換性がありません。 +java.add.not_found=指定されたディレクトリにJavaが見つからないか、Javaディレクトリが深すぎます。 java.disable=無効化 java.disable.confirm=本当にこのJavaを無効にしますか? java.disabled.management=無効なJava diff --git a/HMCL/src/main/resources/assets/lang/I18N_ru.properties b/HMCL/src/main/resources/assets/lang/I18N_ru.properties index 6e6e513e41..40384385fa 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_ru.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_ru.properties @@ -481,6 +481,7 @@ install.success=Успешно установлено. java.add=Добавить Java java.add.failed=Этот Java недопустим или несовместим с текущей платформой. java.add.failed.some=Некоторые из найденных Java недопустимы или несовместимы с текущей платформой. +java.add.not_found=Java не найдена в указанном каталоге, или каталог Java находится слишком глубоко. java.disable=Отключить Java java.disable.confirm=Вы уверены, что хотите отключить эту Java? java.disabled.management=Отключенная Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index a0308b4212..bc417935b1 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -520,6 +520,7 @@ install.success=安裝成功 java.add=添加 Java java.add.failed=Java 無效或與目前平臺不相容 java.add.failed.some=找到的某些 Java 無效或與目前平臺不相容 +java.add.not_found=在指定目錄中找不到 Java,或 Java 目錄太深。 java.disable=禁用此 Java java.disable.confirm=你確定要禁用此 Java 嗎? java.disabled.management=管理已禁用的 Java diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 12f9c78583..5a81f84280 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -531,6 +531,7 @@ install.success=安装成功 java.add=添加 Java java.add.failed=Java 无效或与当前平台不兼容。 java.add.failed.some=找到的部分 Java 无效或与当前平台不兼容。 +java.add.not_found=在指定目录中找不到 Java,或 Java 目录太深。 java.disable=禁用此 Java java.disable.confirm=你确定要禁用此 Java 吗? java.disabled.management=管理已禁用的 Java From d46f6c3b9cbc2d9118ac4d5cd924f76dac95a6ea Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sun, 15 Dec 2024 19:57:49 +0800 Subject: [PATCH 06/11] Add a warning when Java not found --- .../org/jackhuang/hmcl/ui/main/JavaManagementPage.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index 60cfa0e8a2..ebf8b21c17 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -125,11 +125,14 @@ void onShowRestoreJavaPage() { } private void onSearchAndAddJavaBinary(File directory) { - Task task = JavaManager.getSearchAndAddJavaTask(directory).whenComplete(Schedulers.javafx(), exception -> { - if (exception instanceof UnsupportedPlatformException) { + Task task = JavaManager.getSearchAndAddJavaTask(directory).thenAcceptAsync(Schedulers.javafx(), javaRuntimes -> { + if(javaRuntimes.isEmpty()) + Controllers.dialog(i18n("java.add.not_found"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING); + }).whenComplete(Schedulers.javafx(), exception -> { + if(exception instanceof UnsupportedPlatformException) { LOG.warning("Failed to add java", exception); Controllers.dialog(i18n("java.add.failed.some"), i18n("message.error"), MessageDialogPane.MessageType.ERROR); - } else LOG.warning("Other exception when add java", exception); + } else if(exception != null) LOG.warning("Other exception when add java", exception); }); Controllers.taskDialog(task, i18n("java.add"), TaskCancellationAction.NORMAL); } From 497fa8246a0eaac641996b9e3b04fba9ea51ee06 Mon Sep 17 00:00:00 2001 From: ri fumo Date: Mon, 16 Dec 2024 01:01:58 +0800 Subject: [PATCH 07/11] If select Java Home, it is considered a single Java has been selected --- .../java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index ebf8b21c17..07864eea86 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -111,7 +111,9 @@ void onAddJava() { File directory = chooser.showDialog(Controllers.getStage()); if(directory == null) return; - final File file = new File(directory, OperatingSystem.CURRENT_OS.getJavaExecutable()); + File file = new File(directory, OperatingSystem.CURRENT_OS.getJavaExecutable()); + file = file.exists()? file + : new File(file, "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable()); if(file.exists()) { onAddJavaBinary(file.toPath()); return; From 1d95e2f6b5da9705e05c7c54de60a62bd21db2aa Mon Sep 17 00:00:00 2001 From: ri fumo Date: Mon, 16 Dec 2024 22:52:27 +0800 Subject: [PATCH 08/11] When using JDK 8 or earlier, redirect to the "jre" directory. --- .../java/org/jackhuang/hmcl/java/JavaManager.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index f18acc38af..103c762c40 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -209,9 +209,15 @@ private List searchJava() throws IOException, InterruptedException fileQueue.add(directory); continue; } - final File binary = new File(dir, relative); - if (binary.exists()) { - binaryList.add(JavaManager.getJava(binary.toPath())); + Path binary = dir.toPath().resolve(relative); + if (Files.exists(binary)) { + JavaRuntime java = JavaManager.getJava(binary); + if(java.getParsedVersion() <= 8 && java.isJDK()) { + binary = dir.toPath().resolve("jre").resolve(relative); + if(Files.exists(binary)) + java = JavaManager.getJava(binary); + } + binaryList.add(java); continue; } if(depth < maxDepth) { From 09c08d5453da05546f154a1840ad23e15d97363e Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sat, 28 Dec 2024 15:50:12 +0800 Subject: [PATCH 09/11] Search Java task as anonymous inner class --- .../org/jackhuang/hmcl/java/JavaManager.java | 131 +++++++++--------- 1 file changed, 62 insertions(+), 69 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index 103c762c40..5cab71e413 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -177,81 +177,74 @@ public static void refresh() { }).start(); } - private static class SearchJavaTask extends Task> { - - private final File directory; - - SearchJavaTask(File directory, String name) { - this.directory = directory; - setName(name); - } - - @Override - public void execute() throws Exception { - setResult(searchJava()); - } + public static Task> getSearchAndAddJavaTask(File directory) { + return new Task>() { - private List searchJava() throws IOException, InterruptedException { - final int maxDepth = 3; + private final File dir = directory; + { setName("Search Java"); } - File[] subDirs = directory.listFiles(File::isDirectory); - if(subDirs == null) return Collections.emptyList(); - List binaryList = new ArrayList<>(); - Queue fileQueue = new LinkedList<>(Arrays.asList(subDirs)); - fileQueue.add(directory); - final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); - int depth = 1; - while(!fileQueue.isEmpty()) { - final File dir = fileQueue.poll(); - if (dir == directory) { - depth++; - if (!fileQueue.isEmpty() && depth < maxDepth) - fileQueue.add(directory); - continue; - } - Path binary = dir.toPath().resolve(relative); - if (Files.exists(binary)) { - JavaRuntime java = JavaManager.getJava(binary); - if(java.getParsedVersion() <= 8 && java.isJDK()) { - binary = dir.toPath().resolve("jre").resolve(relative); - if(Files.exists(binary)) - java = JavaManager.getJava(binary); - } - binaryList.add(java); - continue; - } - if(depth < maxDepth) { - subDirs = dir.listFiles(File::isDirectory); - if (subDirs != null) - fileQueue.addAll(Arrays.asList(subDirs)); - } - if(isCancelled()) - return Collections.emptyList(); + @Override + public void execute() throws Exception { + setResult(searchJava()); } - return Collections.unmodifiableList(binaryList); - } - } - public static Task> getSearchAndAddJavaTask(File directory) { - return new SearchJavaTask(directory, "Search Java") - .thenApplyAsync("Add Java", Schedulers.javafx(), javaRuntimes -> { - ArrayList failedJavaRuntimes = new ArrayList<>(); - for(JavaRuntime javaRuntime: javaRuntimes) { - if(!JavaManager.isCompatible(javaRuntime.getPlatform())) - failedJavaRuntimes.add(javaRuntime); - String pathString = javaRuntime.getBinary().toString(); - ConfigHolder.globalConfig().getDisabledJava().remove(pathString); - if(ConfigHolder.globalConfig().getUserJava().add(pathString)) - addJava(javaRuntime); + private List searchJava() throws IOException, InterruptedException { + final int maxDepth = 3; + + File[] subDirs = dir.listFiles(File::isDirectory); + if(subDirs == null) return Collections.emptyList(); + List binaryList = new ArrayList<>(); + Queue fileQueue = new LinkedList<>(Arrays.asList(subDirs)); + fileQueue.add(dir); + final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); + int depth = 1; + while(!fileQueue.isEmpty()) { + final File directory = fileQueue.poll(); + if (directory == dir) { + depth++; + if (!fileQueue.isEmpty() && depth < maxDepth) + fileQueue.add(directory); + continue; } - if(!failedJavaRuntimes.isEmpty()) { - StringBuilder sb = new StringBuilder("Incompatible platform: "); - for(JavaRuntime javaRuntime :javaRuntimes) - sb.append('\n').append(javaRuntime.getPlatform()).append(": ").append(javaRuntime.getBinary()); - throw new UnsupportedPlatformException(sb.toString()); + Path binary = directory.toPath().resolve(relative); + if (Files.exists(binary)) { + JavaRuntime java = JavaManager.getJava(binary); + if(java.getParsedVersion() <= 8 && java.isJDK()) { + binary = directory.toPath().resolve("jre").resolve(relative); + if(Files.exists(binary)) + java = JavaManager.getJava(binary); + } + binaryList.add(java); + continue; } - return javaRuntimes; - }); + if(depth < maxDepth) { + subDirs = directory.listFiles(File::isDirectory); + if (subDirs != null) + fileQueue.addAll(Arrays.asList(subDirs)); + } + if(isCancelled()) + return Collections.emptyList(); + } + return Collections.unmodifiableList(binaryList); + } + }.thenApplyAsync("Add Java", Schedulers.javafx(), javaRuntimes -> { + ArrayList failedJavaRuntimes = new ArrayList<>(); + for(JavaRuntime javaRuntime: javaRuntimes) { + if(!JavaManager.isCompatible(javaRuntime.getPlatform())) + failedJavaRuntimes.add(javaRuntime); + String pathString = javaRuntime.getBinary().toString(); + ConfigHolder.globalConfig().getDisabledJava().remove(pathString); + if(ConfigHolder.globalConfig().getUserJava().add(pathString)) + addJava(javaRuntime); + } + if(!failedJavaRuntimes.isEmpty()) { + StringBuilder sb = new StringBuilder("Incompatible platform: "); + for(JavaRuntime javaRuntime :javaRuntimes) + sb.append('\n').append(javaRuntime.getPlatform()).append(": ").append(javaRuntime.getBinary()); + throw new UnsupportedPlatformException(sb.toString()); + } + return javaRuntimes; + }); } public static Task getAddJavaTask(Path binary) { From 7bb37e5946ae6b464c3d73531c6c51f58f7e9a76 Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sat, 28 Dec 2024 21:26:20 +0800 Subject: [PATCH 10/11] Switch from java.io.File to java.nio.file.Path --- .../org/jackhuang/hmcl/java/JavaManager.java | 38 ++++++++++--------- .../hmcl/ui/main/JavaManagementPage.java | 19 +++++----- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index 5cab71e413..7d6a967294 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -41,13 +41,13 @@ import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; -import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.nio.file.*; import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.jackhuang.hmcl.util.logging.Logger.LOG; @@ -177,10 +177,10 @@ public static void refresh() { }).start(); } - public static Task> getSearchAndAddJavaTask(File directory) { + public static Task> getSearchAndAddJavaTask(Path directory) { return new Task>() { - private final File dir = directory; + private final Path dir = directory; { setName("Search Java"); } @Override @@ -191,37 +191,39 @@ public void execute() throws Exception { private List searchJava() throws IOException, InterruptedException { final int maxDepth = 3; - File[] subDirs = dir.listFiles(File::isDirectory); - if(subDirs == null) return Collections.emptyList(); List binaryList = new ArrayList<>(); - Queue fileQueue = new LinkedList<>(Arrays.asList(subDirs)); - fileQueue.add(dir); - final String relative = "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable(); + Queue fileQueue; + try(Stream subDirs = Files.list(dir)) { + fileQueue = subDirs.filter(Files::isDirectory).filter(Files::isReadable) + .collect(Collectors.toCollection(LinkedList::new)); + } + fileQueue.add(null); + final Path relative = Paths.get("bin", OperatingSystem.CURRENT_OS.getJavaExecutable()); int depth = 1; while(!fileQueue.isEmpty()) { - final File directory = fileQueue.poll(); - if (directory == dir) { + final Path directory = fileQueue.poll(); + if (directory == null) { depth++; if (!fileQueue.isEmpty() && depth < maxDepth) - fileQueue.add(directory); + fileQueue.add(null); continue; } - Path binary = directory.toPath().resolve(relative); + Path binary = directory.resolve(relative); if (Files.exists(binary)) { JavaRuntime java = JavaManager.getJava(binary); if(java.getParsedVersion() <= 8 && java.isJDK()) { - binary = directory.toPath().resolve("jre").resolve(relative); + binary = directory.resolve("jre").resolve(relative); if(Files.exists(binary)) java = JavaManager.getJava(binary); } binaryList.add(java); continue; } - if(depth < maxDepth) { - subDirs = directory.listFiles(File::isDirectory); - if (subDirs != null) - fileQueue.addAll(Arrays.asList(subDirs)); - } + if(depth < maxDepth) + try(Stream subDirs = Files.list(directory)) { + fileQueue.addAll(subDirs.filter(Files::isDirectory).filter(Files::isReadable) + .collect(Collectors.toList())); + } if(isCancelled()) return Collections.emptyList(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index 07864eea86..e34c66e596 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -108,14 +108,15 @@ protected Skin createDefaultSkin() { void onAddJava() { final DirectoryChooser chooser = new DirectoryChooser(); chooser.setTitle(i18n("settings.game.java_directory.choose")); - File directory = chooser.showDialog(Controllers.getStage()); - if(directory == null) return; - - File file = new File(directory, OperatingSystem.CURRENT_OS.getJavaExecutable()); - file = file.exists()? file - : new File(file, "bin" + File.separator + OperatingSystem.CURRENT_OS.getJavaExecutable()); - if(file.exists()) { - onAddJavaBinary(file.toPath()); + File dir = chooser.showDialog(Controllers.getStage()); + if(dir == null) return; + Path directory = dir.toPath(); + + Path file = directory.resolve(OperatingSystem.CURRENT_OS.getJavaExecutable()); + file = Files.exists(file)? file + : directory.resolve("bin").resolve(OperatingSystem.CURRENT_OS.getJavaExecutable()); + if(Files.exists(file)) { + onAddJavaBinary(file); return; } @@ -126,7 +127,7 @@ void onShowRestoreJavaPage() { Controllers.navigate(new JavaRestorePage(ConfigHolder.globalConfig().getDisabledJava())); } - private void onSearchAndAddJavaBinary(File directory) { + private void onSearchAndAddJavaBinary(Path directory) { Task task = JavaManager.getSearchAndAddJavaTask(directory).thenAcceptAsync(Schedulers.javafx(), javaRuntimes -> { if(javaRuntimes.isEmpty()) Controllers.dialog(i18n("java.add.not_found"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING); From 5d387d576465b2cf35d8d4dc1272ad805fe147ad Mon Sep 17 00:00:00 2001 From: ri fumo Date: Sun, 29 Dec 2024 04:46:03 +0800 Subject: [PATCH 11/11] Optimize cancellation --- .../java/org/jackhuang/hmcl/java/JavaManager.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java index 7d6a967294..b42471a5ce 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/java/JavaManager.java @@ -45,6 +45,7 @@ import java.io.InputStreamReader; import java.nio.file.*; import java.util.*; +import java.util.concurrent.CancellationException; import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -202,14 +203,16 @@ private List searchJava() throws IOException, InterruptedException int depth = 1; while(!fileQueue.isEmpty()) { final Path directory = fileQueue.poll(); - if (directory == null) { + if(directory == null) { depth++; - if (!fileQueue.isEmpty() && depth < maxDepth) + if(!fileQueue.isEmpty() && depth < maxDepth) fileQueue.add(null); continue; } + if(isCancelled()) + throw new CancellationException("Cancelled by user"); Path binary = directory.resolve(relative); - if (Files.exists(binary)) { + if(Files.exists(binary)) { JavaRuntime java = JavaManager.getJava(binary); if(java.getParsedVersion() <= 8 && java.isJDK()) { binary = directory.resolve("jre").resolve(relative); @@ -217,15 +220,11 @@ private List searchJava() throws IOException, InterruptedException java = JavaManager.getJava(binary); } binaryList.add(java); - continue; - } - if(depth < maxDepth) + } else if(depth < maxDepth) try(Stream subDirs = Files.list(directory)) { fileQueue.addAll(subDirs.filter(Files::isDirectory).filter(Files::isReadable) .collect(Collectors.toList())); } - if(isCancelled()) - return Collections.emptyList(); } return Collections.unmodifiableList(binaryList); }