mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-08 03:15:17 -04:00
修复 Java 管理页面无法添加 IKVM 的问题 (#3968)
This commit is contained in:
parent
d9d32eab1d
commit
d317844b28
@ -41,6 +41,7 @@ dependencies {
|
|||||||
implementation(project(":HMCLCore"))
|
implementation(project(":HMCLCore"))
|
||||||
implementation("libs:JFoenix")
|
implementation("libs:JFoenix")
|
||||||
implementation(libs.twelvemonkeys.imageio.webp)
|
implementation(libs.twelvemonkeys.imageio.webp)
|
||||||
|
implementation(libs.java.info)
|
||||||
|
|
||||||
if (launcherExe == null) {
|
if (launcherExe == null) {
|
||||||
implementation("org.glavo.hmcl:HMCLauncher:3.6.0.2")
|
implementation("org.glavo.hmcl:HMCLauncher:3.6.0.2")
|
||||||
|
@ -168,7 +168,7 @@ public final class HMCLJavaRepository implements JavaRepository {
|
|||||||
|
|
||||||
JavaInfo info;
|
JavaInfo info;
|
||||||
if (JavaManager.isCompatible(platform))
|
if (JavaManager.isCompatible(platform))
|
||||||
info = JavaInfo.fromExecutable(executable, false);
|
info = JavaInfoUtils.fromExecutable(executable, false);
|
||||||
else
|
else
|
||||||
info = new JavaInfo(platform, result.download.getVersion().getName(), null);
|
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.CacheRepository;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.Architecture;
|
import org.jackhuang.hmcl.util.platform.*;
|
||||||
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.windows.WinReg;
|
import org.jackhuang.hmcl.util.platform.windows.WinReg;
|
||||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -162,7 +159,7 @@ public final class JavaManager {
|
|||||||
return javaRuntime;
|
return javaRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaInfo info = JavaInfo.fromExecutable(executable);
|
JavaInfo info = JavaInfoUtils.fromExecutable(executable, true);
|
||||||
return JavaRuntime.of(executable, info, false);
|
return JavaRuntime.of(executable, info, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,7 +481,7 @@ public final class JavaManager {
|
|||||||
info = JavaInfo.fromReleaseFile(releaseFile);
|
info = JavaInfo.fromReleaseFile(releaseFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
info = JavaInfo.fromExecutable(executable, false);
|
info = JavaInfoUtils.fromExecutable(executable, false);
|
||||||
} catch (IOException e2) {
|
} catch (IOException e2) {
|
||||||
e2.addSuppressed(e);
|
e2.addSuppressed(e);
|
||||||
LOG.warning("Failed to lookup Java executable at " + executable, e2);
|
LOG.warning("Failed to lookup Java executable at " + executable, e2);
|
||||||
@ -509,7 +506,7 @@ public final class JavaManager {
|
|||||||
|
|
||||||
JavaInfo info = null;
|
JavaInfo info = null;
|
||||||
try {
|
try {
|
||||||
info = JavaInfo.fromExecutable(executable);
|
info = JavaInfoUtils.fromExecutable(executable, true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warning("Failed to lookup Java executable at " + executable, 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"));
|
public static final JavaInfo CURRENT_ENVIRONMENT = new JavaInfo(Platform.CURRENT_PLATFORM, System.getProperty("java.version"), System.getProperty("java.vendor"));
|
||||||
|
|
||||||
private final Platform platform;
|
private final Platform platform;
|
||||||
|
@ -14,6 +14,7 @@ chardet = "2.5.0"
|
|||||||
twelvemonkeys = "3.12.0"
|
twelvemonkeys = "3.12.0"
|
||||||
jna = "5.17.0"
|
jna = "5.17.0"
|
||||||
pci-ids = "0.4.0"
|
pci-ids = "0.4.0"
|
||||||
|
java-info = "1.0"
|
||||||
|
|
||||||
# plugins
|
# plugins
|
||||||
shadow = "8.3.6"
|
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 = { module = "net.java.dev.jna:jna", version.ref = "jna" }
|
||||||
jna-platform = { module = "net.java.dev.jna:jna-platform", 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" }
|
pci-ids = { module = "org.glavo:pci-ids", version.ref = "pci-ids" }
|
||||||
|
java-info = { module = "org.glavo:java-info", version.ref = "java-info" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user