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

Java 9第三方模块在IDE正常运行但jlink打包自定义JRE失败求助

嘿,这个问题我之前帮人排查过,核心原因是jlink对模块的要求比IDEA严格多了——IDEA能自动处理那些非模块化的第三方JAR(也就是自动模块),但jlink在JDK9里只认带module-info.java的显式模块,这就是你打包时出错的关键。咱们一步步来解决:

问题根源拆解

你用到的poi-3.17.jar、commons-io-2.6.jar、HikariCP-3.1.0.jar都是非模块化的JAR,在IDEA运行时,它们会被当作「自动模块」加载,但jlink不允许将自动模块包含到自定义JRE中,因为它需要明确的模块边界和依赖声明。

具体解决方案

1. 先搞清楚第三方JAR的自动模块名

首先得知道这些JAR对应的模块名,用下面的命令逐个查看:

jar --file=poi-3.17.jar --describe-module
jar --file=commons-io-2.6.jar --describe-module
jar --file=HikariCP-3.1.0.jar --describe-module

举个例子,commons-io-2.6.jar的自动模块名通常是commons.io,HikariCP-3.1.0.jar大概率是com.zaxxer.hikari(如果JAR的MANIFEST里没指定,就是文件名去掉版本号,把连字符换成点)。

2. 把非模块化JAR转成显式模块

有两种靠谱的方式:

方式一:手动添加module-info.java

适合小范围的依赖转换:

  1. 先解压JAR文件:
    unzip poi-3.17.jar -d poi-module
    
  2. 在解压后的poi-module根目录创建module-info.java,根据你的代码依赖编写声明,比如:
    module poi {
        // 导出你代码用到的POI包,比如操作Excel的核心包
        exports org.apache.poi.ss.usermodel;
        // 声明依赖的其他模块
        requires commons.io;
        requires java.desktop;
        // 如果用到反射调用POI内部类,还要用opens声明
        // opens org.apache.poi.xssf.usermodel to your.module.name;
    }
    
  3. 重新打包成模块化JAR:
    jar --create --file=poi-modular.jar -C poi-module .
    
    对commons-io和HikariCP重复这个步骤。

方式二:用Moditect Maven插件自动生成

如果是Maven项目,这个插件能帮你自动给第三方JAR生成module-info.java并打包,省手动操作的麻烦。在pom.xml里加这段配置:

<plugin>
    <groupId>org.moditect</groupId>
    <artifactId>moditect-maven-plugin</artifactId>
    <version>1.0.0.Final</version>
    <executions>
        <execution>
            <id>add-module-info-to-deps</id>
            <phase>package</phase>
            <goals>
                <goal>add-module-info</goal>
            </goals>
            <configuration>
                <modules>
                    <module>
                        <artifact>
                            <groupId>org.apache.poi</groupId>
                            <artifactId>poi</artifactId>
                            <version>3.17</version>
                        </artifact>
                        <moduleInfo>
                            <name>poi</name>
                            <exports>org.apache.poi.ss.usermodel</exports>
                            <requires>commons.io</requires>
                            <requires>java.desktop</requires>
                        </moduleInfo>
                    </module>
                    <!-- 给commons-io和HikariCP也加类似的配置 -->
                    <module>
                        <artifact>
                            <groupId>commons-io</groupId>
                            <artifactId>commons-io</artifactId>
                            <version>2.6</version>
                        </artifact>
                        <moduleInfo>
                            <name>commons.io</name>
                            <exports>org.apache.commons.io</exports>
                        </moduleInfo>
                    </module>
                </modules>
            </configuration>
        </execution>
    </executions>
</plugin>

执行mvn package后,插件会自动生成带module-info.java的模块化JAR。

3. 重新执行jlink命令

把转换后的模块化第三方JAR放到--module-path里,然后在--add-modules中加上这些模块名。比如:

jlink --module-path production:./modular-jars \
      --add-modules studyModule,poi,commons.io,com.zaxxer.hikari,java.base,java.datatransfer,java.desktop,java.logging,java.scripting,java.sql,java.xml,java.prefs,javafx.base,javafx.controls \
      --output custom-jre

这里的./modular-jars是你存放转换后模块化JAR的目录,确保所有依赖的模块都被包含进来。

额外小技巧

如果不确定要加哪些模块,可以用jdeps工具分析你的主模块依赖:

jdeps --module-path your-module-path --list-deps studyModule

它会列出所有直接和间接依赖的模块,照着加就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:12:00