“找不到 jar 文件系统提供程序”尝试使用 jdeps 和 jlink 创建收缩 Java 映像来运行 Minecraft

问题描述 投票:0回答:1

我正在尝试使用

jdeps
jlink
创建一个收缩 Java 映像来运行 Minecraft 1.20.1 客户端(即仅使用运行 Minecraft 所需的最少 Java 模块),但是我遇到了错误,我希望得到一些指导。这就是我所做的:

我将 1.20.1 清单中列出的库下载到我的 ~/.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
作为
$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 源代码中的某个时刻存在未处理的异常。

使用 MCP(Minecraft 源代码的反编译版本)我设法找到了引发错误的相关代码片段:

// 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 文件系统”在哪里定义的?欢迎任何帮助,提前致谢:)

java jar minecraft jlink jdeps
1个回答
0
投票

尝试将模块

jdk.zipfs
添加到您的列表中,该模块应该提供 zip 文件系统。

© www.soinside.com 2019 - 2024. All rights reserved.