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

如何在jlink中使用签名模块化JAR并规避JCE Provider运行报错?

解决jlink构建含签名JCE Provider(如BouncyCastle)的运行时镜像问题

咱们先把问题拆解清楚:你用jlink打包时遇到的是签名模块化JAR不被jlink支持,以及后续运行时JCE Provider签名验证失败的双重矛盾——BouncyCastle作为第三方JCE Provider,必须签名才能被JVM信任,但jlink没法直接处理签名的模块化JAR,强行用--ignore-signing-information跳过检查后,运行时又会因为签名验证失败抛出异常。

下面给你几个可行的解决办法,按实用程度排序:


方案1:将BouncyCastle作为外部依赖加载(最稳妥)

既然jlink搞不定签名JAR,那咱们就不把它打包进镜像,让运行时从外部加载:

  1. 调整jlink命令,不要把bcprov.jdk15on.jar加入--module-path,也不要在--add-modules里包含它的模块
  2. 把bcprov.jdk15on.jar放到应用目录下的单独文件夹,比如./lib/
  3. 运行生成的可执行文件时,通过参数指定这个外部JAR:
    # 模块化方式加载
    ./dist/bin/launch --module-path ./lib/bcprov.jdk15on.jar --add-modules org.bouncycastle
    # 或者类路径方式(如果你的应用不是模块化的)
    ./dist/bin/launch -cp ./lib/bcprov.jdk15on.jar
    
    这种方式彻底避开了jlink和签名JAR的冲突,JVM也能正常验证BouncyCastle的签名,不会出现认证异常。

方案2:用jpackage配合打包(适合生成安装包)

如果你需要生成单文件或系统安装包,可以结合jpackage和jlink来处理:

  1. 先构建不含BouncyCastle的jlink镜像(也就是去掉模块路径里的bcprov.jdk15on.jar)
  2. 用jpackage打包时,通过--input参数指定存放bcprov.jdk15on.jar的目录,jpackage会自动把它放到应用的lib目录并配置好加载路径:
    jpackage --name MyDemoApp --module org.demo/org.demo.Main --runtime-image dist --input ./lib
    
    这样生成的安装包会自动处理外部依赖,运行时能正确加载并验证BouncyCastle。

方案3:修改BouncyCastle JAR为非签名模块化JAR(不推荐,有安全风险)

如果你一定要把BouncyCastle打包进镜像,可以尝试移除它的签名并重新模块化:

  1. 解压bcprov.jdk15on.jar,删除META-INF目录下的所有签名相关文件(比如.SF、.DSA、.RSA后缀的文件)
  2. 添加module-info.java文件(如果原JAR没有模块化描述的话),示例内容如下:
    module org.bouncycastle {
        exports org.bouncycastle.jce.provider;
        provides java.security.Provider with org.bouncycastle.jce.provider.BouncyCastleProvider;
        requires java.base;
        requires java.security.jgss;
        // 根据你的实际使用情况添加其他依赖模块
    }
    
  3. 重新编译并打包成模块化JAR:
    # 编译module-info.java
    javac --module-path . -d tmp module-info.java
    # 重新打包JAR
    jar --create --file bcprov-mod.jar -C tmp . -C ./original-bc-unpacked .
    
  4. 用这个修改后的非签名JAR执行jlink命令,不需要加--ignore-signing-information,运行时也不会抛出异常。

    注意:这种方式会失去JCE Provider的签名验证机制,存在安全隐患,不建议在生产环境使用。


问题根源补充

  • jlink的--ignore-signing-information只是在打包阶段跳过了签名检查,但JVM运行时依然会严格验证JCE Provider的签名。而jlink在打包过程中会重新处理模块内容,导致原JAR的签名信息被破坏,所以运行时会抛出Non-Oracle JCE providers may not be linked into the image异常。
  • Oracle JVM对JCE Provider有强制签名要求,第三方Provider必须经过签名才能被加载,但目前jlink还不支持保留签名模块化JAR的完整性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:10:35