mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-08-03 11:26:38 -04:00
修复 Java 管理页面无法添加 IKVM 的问题 (#3968)
This commit is contained in:
parent
d9d32eab1d
commit
d317844b28
@ -41,6 +41,7 @@ dependencies {
|
||||
implementation(project(":HMCLCore"))
|
||||
implementation("libs:JFoenix")
|
||||
implementation(libs.twelvemonkeys.imageio.webp)
|
||||
implementation(libs.java.info)
|
||||
|
||||
if (launcherExe == null) {
|
||||
implementation("org.glavo.hmcl:HMCLauncher:3.6.0.2")
|
||||
|
@ -168,7 +168,7 @@ public final class HMCLJavaRepository implements JavaRepository {
|
||||
|
||||
JavaInfo info;
|
||||
if (JavaManager.isCompatible(platform))
|
||||
info = JavaInfo.fromExecutable(executable, false);
|
||||
info = JavaInfoUtils.fromExecutable(executable, false);
|
||||
else
|
||||
info = new JavaInfo(platform, result.download.getVersion().getName(), null);
|
||||
|
||||
|
116
HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java
Normal file
116
HMCL/src/main/java/org/jackhuang/hmcl/java/JavaInfoUtils.java
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.java;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.JarUtils;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.platform.Platform;
|
||||
import org.jackhuang.hmcl.util.platform.SystemUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* @author Glavo
|
||||
* @see <a href="https://github.com/Glavo/java-info">Glavo/java-info</a>
|
||||
*/
|
||||
public final class JavaInfoUtils {
|
||||
|
||||
private JavaInfoUtils() {
|
||||
}
|
||||
|
||||
private static Path tryFindReleaseFile(Path executable) {
|
||||
Path parent = executable.getParent();
|
||||
if (parent != null && parent.getFileName() != null && parent.getFileName().toString().equals("bin")) {
|
||||
Path javaHome = parent.getParent();
|
||||
if (javaHome != null && javaHome.getFileName() != null) {
|
||||
Path releaseFile = javaHome.resolve("release");
|
||||
String javaHomeName = javaHome.getFileName().toString();
|
||||
if ((javaHomeName.contains("jre") || javaHomeName.contains("jdk") || javaHomeName.contains("openj9"))
|
||||
&& Files.isRegularFile(releaseFile)) {
|
||||
return releaseFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @NotNull JavaInfo fromExecutable(Path executable, boolean tryFindReleaseFile) throws IOException {
|
||||
assert executable.isAbsolute();
|
||||
|
||||
Path releaseFile;
|
||||
if (tryFindReleaseFile && (releaseFile = tryFindReleaseFile(executable)) != null) {
|
||||
try {
|
||||
return JavaInfo.fromReleaseFile(releaseFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
Path thisPath = JarUtils.thisJarPath();
|
||||
|
||||
if (thisPath == null) {
|
||||
throw new IOException("Failed to find current HMCL location");
|
||||
}
|
||||
|
||||
try {
|
||||
Result result = JsonUtils.GSON.fromJson(SystemUtils.run(
|
||||
executable.toString(),
|
||||
"-classpath",
|
||||
thisPath.toString(),
|
||||
org.glavo.info.Main.class.getName()
|
||||
), Result.class);
|
||||
|
||||
if (result == null) {
|
||||
throw new IOException("Failed to get Java info from " + executable);
|
||||
}
|
||||
|
||||
if (result.javaVersion == null) {
|
||||
throw new IOException("Failed to get Java version from " + executable);
|
||||
}
|
||||
|
||||
Architecture architecture = Architecture.parseArchName(result.osArch);
|
||||
Platform platform = Platform.getPlatform(OperatingSystem.CURRENT_OS,
|
||||
architecture != Architecture.UNKNOWN
|
||||
? architecture
|
||||
: Architecture.SYSTEM_ARCH);
|
||||
|
||||
|
||||
return new JavaInfo(platform, result.javaVersion, result.javaVendor);
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Result {
|
||||
@SerializedName("os.name")
|
||||
public String osName;
|
||||
@SerializedName("os.arch")
|
||||
public String osArch;
|
||||
@SerializedName("java.version")
|
||||
public String javaVersion;
|
||||
@SerializedName("java.vendor")
|
||||
public String javaVendor;
|
||||
}
|
||||
}
|
@ -32,10 +32,7 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.util.CacheRepository;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.platform.Platform;
|
||||
import org.jackhuang.hmcl.util.platform.UnsupportedPlatformException;
|
||||
import org.jackhuang.hmcl.util.platform.*;
|
||||
import org.jackhuang.hmcl.util.platform.windows.WinReg;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -162,7 +159,7 @@ public final class JavaManager {
|
||||
return javaRuntime;
|
||||
}
|
||||
|
||||
JavaInfo info = JavaInfo.fromExecutable(executable);
|
||||
JavaInfo info = JavaInfoUtils.fromExecutable(executable, true);
|
||||
return JavaRuntime.of(executable, info, false);
|
||||
}
|
||||
|
||||
@ -484,7 +481,7 @@ public final class JavaManager {
|
||||
info = JavaInfo.fromReleaseFile(releaseFile);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
info = JavaInfo.fromExecutable(executable, false);
|
||||
info = JavaInfoUtils.fromExecutable(executable, false);
|
||||
} catch (IOException e2) {
|
||||
e2.addSuppressed(e);
|
||||
LOG.warning("Failed to lookup Java executable at " + executable, e2);
|
||||
@ -509,7 +506,7 @@ public final class JavaManager {
|
||||
|
||||
JavaInfo info = null;
|
||||
try {
|
||||
info = JavaInfo.fromExecutable(executable);
|
||||
info = JavaInfoUtils.fromExecutable(executable, true);
|
||||
} catch (IOException e) {
|
||||
LOG.warning("Failed to lookup Java executable at " + executable, e);
|
||||
}
|
||||
|
@ -136,108 +136,6 @@ public final class JavaInfo {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String OS_ARCH = "os.arch = ";
|
||||
private static final String JAVA_VERSION = "java.version = ";
|
||||
private static final String JAVA_VENDOR = "java.vendor = ";
|
||||
private static final String VERSION_PREFIX = "version \"";
|
||||
|
||||
public static JavaInfo fromExecutable(Path executable) throws IOException {
|
||||
return fromExecutable(executable, true);
|
||||
}
|
||||
|
||||
public static JavaInfo fromExecutable(Path executable, boolean tryFindReleaseFile) throws IOException {
|
||||
assert executable.isAbsolute();
|
||||
Path parent = executable.getParent();
|
||||
if (tryFindReleaseFile && parent != null && parent.getFileName() != null && parent.getFileName().toString().equals("bin")) {
|
||||
Path javaHome = parent.getParent();
|
||||
if (javaHome != null && javaHome.getFileName() != null) {
|
||||
Path releaseFile = javaHome.resolve("release");
|
||||
String javaHomeName = javaHome.getFileName().toString();
|
||||
if ((javaHomeName.contains("jre") || javaHomeName.contains("jdk") || javaHomeName.contains("openj9")) && Files.isRegularFile(releaseFile)) {
|
||||
try {
|
||||
return fromReleaseFile(releaseFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String osArch = null;
|
||||
String version = null;
|
||||
String vendor = null;
|
||||
Platform platform = null;
|
||||
|
||||
String executablePath = executable.toString();
|
||||
|
||||
Process process = new ProcessBuilder(executablePath, "-XshowSettings:properties", "-version").start();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), OperatingSystem.NATIVE_CHARSET))) {
|
||||
for (String line; (line = reader.readLine()) != null; ) {
|
||||
|
||||
int idx = line.indexOf(OS_ARCH);
|
||||
if (idx >= 0) {
|
||||
osArch = line.substring(idx + OS_ARCH.length()).trim();
|
||||
if (version != null && vendor != null)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = line.indexOf(JAVA_VERSION);
|
||||
if (idx >= 0) {
|
||||
version = line.substring(idx + JAVA_VERSION.length()).trim();
|
||||
if (osArch != null && vendor != null)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = line.indexOf(JAVA_VENDOR);
|
||||
if (idx >= 0) {
|
||||
vendor = line.substring(idx + JAVA_VENDOR.length()).trim();
|
||||
if (osArch != null && version != null)
|
||||
break;
|
||||
else
|
||||
//noinspection UnnecessaryContinue
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (osArch != null)
|
||||
platform = Platform.getPlatform(OperatingSystem.CURRENT_OS, Architecture.parseArchName(osArch));
|
||||
|
||||
// Java 6
|
||||
if (version == null) {
|
||||
boolean is64Bit = false;
|
||||
process = new ProcessBuilder(executablePath, "-version").start();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), OperatingSystem.NATIVE_CHARSET))) {
|
||||
for (String line; (line = reader.readLine()) != null; ) {
|
||||
if (version == null) {
|
||||
int idx = line.indexOf(VERSION_PREFIX);
|
||||
if (idx >= 0) {
|
||||
int begin = idx + VERSION_PREFIX.length();
|
||||
int end = line.indexOf('"', begin);
|
||||
if (end >= 0) {
|
||||
version = line.substring(begin, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line.contains("64-Bit"))
|
||||
is64Bit = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (platform == null)
|
||||
platform = Platform.getPlatform(OperatingSystem.CURRENT_OS, is64Bit ? Architecture.X86_64 : Architecture.X86);
|
||||
|
||||
if (version == null)
|
||||
throw new IOException("Cannot determine version");
|
||||
}
|
||||
|
||||
return new JavaInfo(platform, version, vendor);
|
||||
}
|
||||
|
||||
public static final JavaInfo CURRENT_ENVIRONMENT = new JavaInfo(Platform.CURRENT_PLATFORM, System.getProperty("java.version"), System.getProperty("java.vendor"));
|
||||
|
||||
private final Platform platform;
|
||||
|
@ -14,6 +14,7 @@ chardet = "2.5.0"
|
||||
twelvemonkeys = "3.12.0"
|
||||
jna = "5.17.0"
|
||||
pci-ids = "0.4.0"
|
||||
java-info = "1.0"
|
||||
|
||||
# plugins
|
||||
shadow = "8.3.6"
|
||||
@ -36,6 +37,7 @@ twelvemonkeys-imageio-webp = { module = "com.twelvemonkeys.imageio:imageio-webp"
|
||||
jna = { module = "net.java.dev.jna:jna", version.ref = "jna" }
|
||||
jna-platform = { module = "net.java.dev.jna:jna-platform", version.ref = "jna" }
|
||||
pci-ids = { module = "org.glavo:pci-ids", version.ref = "pci-ids" }
|
||||
java-info = { module = "org.glavo:java-info", version.ref = "java-info" }
|
||||
|
||||
[plugins]
|
||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user