You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ClassLoader.getResources()在module-path可用,jlink中失效,是否为JDK Bug?

问题:jlink构建后ClassLoader.getResources()无法找到资源是否属于JDK Bug?

在以下测试场景中,调用ClassLoader.getResources("database/migration"):

  • 直接通过module-path运行时,返回1条结果(符合预期)
  • 经过jlink构建自定义运行时后,返回0条结果(不符合预期)

测试用例详情

模块定义(src/main/java/module-info.java)

module jlink.testcase {
    opens database.migration;
}

主类代码(src/main/java/testcase/Main.java)

package testcase;

import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        List<URL> resources = Collections.list(Main.class.getClassLoader().getResources("database/migration"));
        System.out.println("Found: " + resources);
    }
}

资源文件

src/main/resources/database/migration/V1__placeholder.sql(空文件)

Maven配置(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jlink-testcase</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.release>20</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                            <mainClass>testcase.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

测试脚本

正常运行脚本(good.bat)

@echo off
java -ea --module-path "%JAVA_HOME%\bin\jmods;target\jlink-testcase-1.0-SNAPSHOT.jar" --module jlink.testcase

jlink构建后运行脚本(bad.bat)

@echo off

rd /s /q target\jlink
set JDK_JAVA_OPTIONS=-ea
jlink --add-modules jlink.testcase --module-path "%JAVA_HOME%\bin\jmods;target\jlink-testcase-1.0-SNAPSHOT.jar" --output target\jlink --launcher testcase=jlink.testcase
target\jlink\bin\java --module-path target\jlink-resources-1.0-SNAPSHOT.jar --module jlink.testcase

结论:这不是JDK Bug,而是使用方式错误

问题出在bad.bat的最后一行:你在jlink构建的运行时中额外指定了--module-path target\jlink-resources-1.0-SNAPSHOT.jar,但该jar包并不存在(项目构建产物为jlink-testcase-1.0-SNAPSHOT.jar)。同时jlink已经将jlink.testcase模块打包进自定义运行时,此时指定的module-path会覆盖默认模块路径,导致运行时找不到原本包含资源的模块。

修复方式

修改bad.bat的最后一行,去掉多余的--module-path参数,直接运行:

target\jlink\bin\java --module jlink.testcase

若确实需要加载额外模块,确保module-path指向正确的jar包即可。

另外需要注意:jlink构建的自定义运行时已将目标模块整合到镜像中,默认无需再指定module-path,除非要添加镜像外的额外模块。

内容的提问来源于stack exchange,提问作者Gili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:48:08