我正在尝试使用以下命令创建一个收缩 Java 映像来运行 Minecraft 1.20.1 客户端jdeps
and jlink
(即只需要运行 Minecraft 所需的最少 Java 模块),但是我遇到了错误,我希望得到一些指导。这就是我所做的:
我下载了列出的库1.20.1 清单 https://piston-meta.mojang.com/v1/packages/cdad018fbbe4e10919b560da3d1640d7b6355dbf/1.20.1.json进入我的 ~/.minecraft/libraries 和client.jar
在 ~/.minecraft/versions/1.20.1/1.20.1.jar 中。
为了查找 Minecraft 客户端使用的 Java 模块,我运行了:
jdeps \
-q \
--ignore-missing-deps \
--print-module-deps \
--multi-release 17 \
-cp $HOME'/.minecraft/libraries/*' \
--recursive \
$HOME/.minecraft/versions/1.20.1/1.20.1.jar
这给了我:
java.base,java.compiler,java.desktop,java.management,java.naming,java.rmi,java.scripting,java.security.jgss,java.sql,jdk.jfr,jdk.unsupported
然后我将这些模块传递给jlink
as $modules
:
jlink --no-header-files --compress=2 --no-man-pages --add-modules $modules --output 'custom-jre'
最后,我像往常一样运行 Minecraft 客户端,但现在使用我新创建的收缩 JVM
/path/to/custom-jre/bin/java \
-cp '<whole-list-of-minecraft-jars>' \
net.minecraft.client.main.Main \
--version 1.20.1 \
--gameDir $HOME/.minecraft \
--accessToken <auth-token>
崩溃并显示错误消息:
Exception in thread "main" java.lang.ExceptionInInitializerError
at net.minecraft.client.main.Main.main(SourceFile:83)
Caused by: java.lang.IllegalStateException: No jar file system provider found
at ac.o(SourceFile:101)
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at ac.<clinit>(SourceFile:101)
... 1 more
正如您所看到的,客户端成功启动,但 Minecraft 源代码中的某个时刻存在未处理的异常。
Using MCP https://github.com/Hexeption/MCP-Reborn(《我的世界》源代码的反编译版本)我设法找到了引发错误的相关代码:
// src/main/java/net/minecraft/Util.java
public class Util {
// ....
public static final FileSystemProvider ZIP_FILE_SYSTEM_PROVIDER = FileSystemProvider.installedProviders().stream().filter((p_201865_) -> {
return p_201865_.getScheme().equalsIgnoreCase("jar");
}).findFirst().orElseThrow(() -> {
return new IllegalStateException("No jar file system provider found");
});
// ....
}
我对Java文件系统不是很熟悉,但是基本上找不到“jar”文件系统提供者。我写了这段最小的代码来说明问题:
import java.nio.file.spi.FileSystemProvider;
public class Test {
public static void main(String[] args) {
for (var provider : FileSystemProvider.installedProviders()) {
System.out.println(provider.getScheme().toString());
}
}
}
# Running with the system's JDK 17.0.8 (~259M)
$ java Test
file
jar
jrt
# Running it with my custom JRE: (~58M)
$ /path/to/custom-jre/bin/java Test
file
jrt # <- doesn't have the jar file system
我在这里描述的方法适用于我拥有的每个项目,只有 Minecraft 导致了这个问题。如果有更好的方法,我很乐意看到!
那么什么是合适的解决方案呢?我错过了什么吗? “jar 文件系统”在哪里定义的?欢迎任何帮助,提前致谢:)