feat(java): find java in minecraft runtime directory with any component name. As a new component name "java-runtime-gamma" was added.
This commit is contained in:
@@ -31,7 +31,6 @@ import javafx.stage.Stage;
|
|||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
import org.jackhuang.hmcl.Launcher;
|
import org.jackhuang.hmcl.Launcher;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.download.java.JavaRepository;
|
|
||||||
import org.jackhuang.hmcl.game.ModpackHelper;
|
import org.jackhuang.hmcl.game.ModpackHelper;
|
||||||
import org.jackhuang.hmcl.setting.Accounts;
|
import org.jackhuang.hmcl.setting.Accounts;
|
||||||
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
|
import org.jackhuang.hmcl.setting.EnumCommonDirectory;
|
||||||
@@ -173,7 +172,7 @@ public final class Controllers {
|
|||||||
dialog(i18n("launcher.cache_directory.invalid"));
|
dialog(i18n("launcher.cache_directory.invalid"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.runAsync(JavaVersion::initialize).thenRunAsync(JavaRepository::initialize).start();
|
Task.runAsync(JavaVersion::initialize).start();
|
||||||
|
|
||||||
scene = new Scene(decorator.getDecorator());
|
scene = new Scene(decorator.getDecorator());
|
||||||
scene.setFill(Color.TRANSPARENT);
|
scene.setFill(Color.TRANSPARENT);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.jackhuang.hmcl.download.DownloadProvider;
|
|||||||
import org.jackhuang.hmcl.game.GameJavaVersion;
|
import org.jackhuang.hmcl.game.GameJavaVersion;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.CacheRepository;
|
import org.jackhuang.hmcl.util.CacheRepository;
|
||||||
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||||
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
import org.jackhuang.hmcl.util.platform.JavaVersion;
|
||||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||||
@@ -12,8 +13,11 @@ import java.io.IOException;
|
|||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.DirectoryStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
|
|
||||||
@@ -42,26 +46,48 @@ public final class JavaRepository {
|
|||||||
throw new IOException("Incorrect java home " + javaHome);
|
throw new IOException("Incorrect java home " + javaHome);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initialize() throws IOException, InterruptedException {
|
public static Stream<Optional<Path>> findMinecraftRuntimeDirs() {
|
||||||
Optional<String> platformOptional = getSystemJavaPlatform();
|
switch (OperatingSystem.CURRENT_OS) {
|
||||||
if (platformOptional.isPresent()) {
|
case WINDOWS:
|
||||||
String platform = platformOptional.get();
|
return Stream.of(
|
||||||
Path javaStoragePath = getJavaStoragePath();
|
FileUtils.tryGetPath(System.getenv("localappdata"),
|
||||||
if (Files.isDirectory(javaStoragePath)) {
|
"Packages\\Microsoft.4297127D64EC6_8wekyb3d8bbwe\\LocalCache\\Local\\runtime"),
|
||||||
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(javaStoragePath)) {
|
FileUtils.tryGetPath(
|
||||||
for (Path component : dirStream) {
|
Optional.ofNullable(System.getenv("ProgramFiles(x86)")).orElse("C:\\Program Files (x86)"),
|
||||||
Path javaHome = component.resolve(platform).resolve(component.getFileName());
|
"Minecraft Launcher\\runtime"));
|
||||||
try {
|
case LINUX:
|
||||||
addJava(javaHome);
|
return Stream.of(FileUtils.tryGetPath(System.getProperty("user.home", ".minecraft/runtime")));
|
||||||
} catch (IOException e) {
|
case OSX:
|
||||||
LOG.log(Level.WARNING, "Failed to determine Java at " + javaHome, e);
|
return Stream.of(FileUtils.tryGetPath("/Library/Application Support/minecraft/runtime"),
|
||||||
}
|
FileUtils.tryGetPath(System.getProperty("user.home"), "/Library/Application Support/minecraft/runtime"));
|
||||||
}
|
default:
|
||||||
}
|
return Stream.empty();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Stream<Path> findJavaHomeInMinecraftRuntimeDir(Path runtimeDir) {
|
||||||
|
// Examples:
|
||||||
|
// $HOME/Library/Application Support/minecraft/runtime/java-runtime-beta/mac-os/java-runtime-beta/jre.bundle/Contents/Home
|
||||||
|
// $HOME/.minecraft/runtime/java-runtime-beta/linux/java-runtime-beta
|
||||||
|
Optional<String> platformOptional = getSystemJavaPlatform();
|
||||||
|
if (!platformOptional.isPresent()) return Stream.empty();
|
||||||
|
String platform = platformOptional.get();
|
||||||
|
List<Path> javaHomes = new ArrayList<>();
|
||||||
|
try (DirectoryStream<Path> dir = Files.newDirectoryStream(runtimeDir)) {
|
||||||
|
// component can be jre-legacy, java-runtime-alpha, java-runtime-beta, java-runtime-gamma or any other being added in the future.
|
||||||
|
for (Path component : dir) {
|
||||||
|
Path javaHome = component.resolve(platform).resolve(component.getFileName());
|
||||||
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.OSX) {
|
||||||
|
javaHomes.add(javaHome.resolve("jre.bundle/Contents/Home"));
|
||||||
|
}
|
||||||
|
javaHomes.add(javaHome);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.WARNING, "Failed to list java-runtime directory " + runtimeDir, e);
|
||||||
|
}
|
||||||
|
return javaHomes.stream();
|
||||||
|
}
|
||||||
|
|
||||||
public static Optional<String> getSystemJavaPlatform() {
|
public static Optional<String> getSystemJavaPlatform() {
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
|
||||||
if (Architecture.SYSTEM_ARCH == Architecture.X86) {
|
if (Architecture.SYSTEM_ARCH == Architecture.X86) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.platform;
|
package org.jackhuang.hmcl.util.platform;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.java.JavaRepository;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
@@ -32,7 +33,6 @@ import java.util.concurrent.*;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
@@ -305,13 +305,8 @@ public final class JavaVersion {
|
|||||||
// 2. Minecraft-installed locations
|
// 2. Minecraft-installed locations
|
||||||
// 3. PATH
|
// 3. PATH
|
||||||
List<Stream<Path>> javaExecutables = new ArrayList<>();
|
List<Stream<Path>> javaExecutables = new ArrayList<>();
|
||||||
// Can be not present -- we check at the last part
|
|
||||||
List<Optional<Path>> runtimeDirs = new ArrayList<>();
|
String javaExe = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "java.exe" : "java";
|
||||||
// Is this necessary? Can't we just do listDirectory(...).map(x -> x.resolve(...))?
|
|
||||||
// lookupJavas() should take care of it...
|
|
||||||
List<String> runtimeOSArch = new ArrayList<>();
|
|
||||||
String pathSep = System.getProperty("path.separator");
|
|
||||||
String javaExec = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "java.exe" : "java";
|
|
||||||
|
|
||||||
switch (OperatingSystem.CURRENT_OS) {
|
switch (OperatingSystem.CURRENT_OS) {
|
||||||
case WINDOWS:
|
case WINDOWS:
|
||||||
@@ -332,26 +327,13 @@ public final class JavaVersion {
|
|||||||
javaExecutables.add(listDirectory(programFiles.get().resolve(vendor)).map(JavaVersion::getExecutable));
|
javaExecutables.add(listDirectory(programFiles.get().resolve(vendor)).map(JavaVersion::getExecutable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDirs.add(FileUtils.tryGetPath(System.getenv("localappdata"),
|
|
||||||
"Packages\\Microsoft.4297127D64EC6_8wekyb3d8bbwe\\LocalCache\\Local\\runtime"));
|
|
||||||
runtimeDirs.add(FileUtils.tryGetPath(
|
|
||||||
Optional.ofNullable(System.getenv("ProgramFiles(x86)")).orElse("C:\\Program Files (x86)"),
|
|
||||||
"Minecraft Launcher\\runtime"));
|
|
||||||
|
|
||||||
runtimeOSArch.add("windows-x64");
|
|
||||||
runtimeOSArch.add("windows-x86");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LINUX:
|
case LINUX:
|
||||||
javaExecutables.add(listDirectory(Paths.get("/usr/java")).map(JavaVersion::getExecutable)); // Oracle RPMs
|
javaExecutables.add(listDirectory(Paths.get("/usr/java")).map(JavaVersion::getExecutable)); // Oracle RPMs
|
||||||
javaExecutables.add(listDirectory(Paths.get("/usr/lib/jvm")).map(JavaVersion::getExecutable)); // General locations
|
javaExecutables.add(listDirectory(Paths.get("/usr/lib/jvm")).map(JavaVersion::getExecutable)); // General locations
|
||||||
javaExecutables.add(listDirectory(Paths.get("/usr/lib32/jvm")).map(JavaVersion::getExecutable)); // General locations
|
javaExecutables.add(listDirectory(Paths.get("/usr/lib32/jvm")).map(JavaVersion::getExecutable)); // General locations
|
||||||
|
|
||||||
runtimeDirs.add(FileUtils.tryGetPath(System.getProperty("user.home", ".minecraft/runtime")));
|
|
||||||
runtimeOSArch.add("linux");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case OSX:
|
case OSX:
|
||||||
javaExecutables.add(listDirectory(Paths.get("/Library/Java/JavaVirtualMachines"))
|
javaExecutables.add(listDirectory(Paths.get("/Library/Java/JavaVirtualMachines"))
|
||||||
@@ -362,40 +344,29 @@ public final class JavaVersion {
|
|||||||
.map(JavaVersion::getExecutable));
|
.map(JavaVersion::getExecutable));
|
||||||
javaExecutables.add(Stream.of(Paths.get("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java")));
|
javaExecutables.add(Stream.of(Paths.get("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java")));
|
||||||
javaExecutables.add(Stream.of(Paths.get("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java")));
|
javaExecutables.add(Stream.of(Paths.get("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java")));
|
||||||
|
|
||||||
runtimeDirs.add(FileUtils.tryGetPath("/Library/Application Support/minecraft/runtime"));
|
|
||||||
runtimeDirs.add(FileUtils.tryGetPath(System.getProperty("user.home"), "/Library/Application Support/minecraft/runtime"));
|
|
||||||
|
|
||||||
runtimeOSArch.add("mac-os");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do MC runtimes, given the OS-specific info we have.
|
// Search Minecraft bundled runtimes.
|
||||||
for (Optional<Path> runtimeDir : runtimeDirs) {
|
javaExecutables.add(Stream.concat(Stream.of(Optional.of(JavaRepository.getJavaStoragePath())), JavaRepository.findMinecraftRuntimeDirs())
|
||||||
if (!runtimeDir.isPresent())
|
.flatMap(Lang::toStream)
|
||||||
continue;
|
.flatMap(JavaRepository::findJavaHomeInMinecraftRuntimeDir)
|
||||||
|
.map(JavaVersion::getExecutable));
|
||||||
for (String osArch : runtimeOSArch) {
|
|
||||||
javaExecutables.add(Stream.of(
|
// Search in PATH.
|
||||||
runtimeDir.get().resolve("jre-legacy").resolve(osArch).resolve("jre-legacy"),
|
if (System.getenv("PATH") != null) {
|
||||||
runtimeDir.get().resolve("java-runtime-alpha").resolve(osArch).resolve("java-runtime-alpha"),
|
javaExecutables.add(Arrays.stream(System.getenv("PATH").split(OperatingSystem.PATH_SEPARATOR))
|
||||||
runtimeDir.get().resolve("java-runtime-beta").resolve(osArch).resolve("java-runtime-beta"))
|
.flatMap(path -> Lang.toStream(FileUtils.tryGetPath(path, javaExe))));
|
||||||
.map(x -> OperatingSystem.CURRENT_OS == OperatingSystem.OSX ? x.resolve("jre.bundle/Contents/Home") : x)
|
|
||||||
.map(JavaVersion::getExecutable));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do PATH.
|
// Search in HMCL_JRES, convenient environment variable for users to add JRE in global
|
||||||
if (System.getenv("PATH") != null) {
|
// May be removed when we implement global Java configuration.
|
||||||
javaExecutables.add(Arrays.stream(System.getenv("PATH").split(pathSep))
|
|
||||||
.flatMap(path -> Lang.toStream(FileUtils.tryGetPath(path, javaExec))));
|
|
||||||
}
|
|
||||||
if (System.getenv("HMCL_JRES") != null) {
|
if (System.getenv("HMCL_JRES") != null) {
|
||||||
javaExecutables.add(Arrays.stream(System.getenv("HMCL_JRES").split(pathSep))
|
javaExecutables.add(Arrays.stream(System.getenv("HMCL_JRES").split(OperatingSystem.PATH_SEPARATOR))
|
||||||
.flatMap(path -> Lang.toStream(FileUtils.tryGetPath(path, "bin", javaExec))));
|
.flatMap(path -> Lang.toStream(FileUtils.tryGetPath(path, "bin", javaExe))));
|
||||||
}
|
}
|
||||||
return javaExecutables.parallelStream().flatMap(stream -> stream);
|
return javaExecutables.parallelStream().flatMap(stream -> stream);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user