基于Adoptium的Java17 Docker镜像使用--add-opens报未识别选项错误
问题根因
报错和Java版本、基础镜像无关,核心是JVM参数传递格式错误:
--add-opens本身是独立的JVM选项,它后面跟随的模块开放规则是另一个独立的命令行参数,二者不能合并写在同一个参数字符串中- Jib插件的
<jvmFlag>配置每一条对应一个独立的、直接传给java进程的命令行参数,不会自动按空格拆分参数 - 你导出的镜像Entrypoint已经明确体现了问题:两个
--add-opens配置被合并成了单个字符串参数,Docker exec启动模式没有shell做参数拆分,JVM收到的是一个名为--add-opens java.base/sun.security.ssl=ALL-UNNAMED的完整未知选项,直接抛出识别错误。
你本地开发环境能正常运行,是因为本地通过shell启动时,shell会自动按空格把整行命令拆分为独立参数传给JVM,和容器内的exec启动逻辑完全不同。
解决方案
修改Jib插件的jvmFlags配置,把每个--add-opens和对应的模块配置拆分为独立的<jvmFlag>条目:
<jvmFlags> <jvmFlag>--add-opens</jvmFlag> <jvmFlag>java.base/sun.security.ssl=ALL-UNNAMED</jvmFlag> <jvmFlag>--add-opens</jvmFlag> <jvmFlag>java.base/sun.security.util=ALL-UNNAMED</jvmFlag> </jvmFlags>
重新构建镜像即可正常启动。构建完成后可以导出镜像查看config.json,正确的Entrypoint参数格式应当如下:
"Entrypoint":[ "java", "--add-opens", "java.base/sun.security.ssl=ALL-UNNAMED", "--add-opens", "java.base/sun.security.util=ALL-UNNAMED", "-cp", "@/app/jib-classpath-file", "com.example.demo.DemoApplication" ],
注:如果后续通过
JAVA_TOOL_OPTIONS传递参数不存在这个问题,因为JVM会自行解析该环境变量内的空格分隔参数,之前用该方式报错大概率是配置时存在多余引号、转义错误等问题。
内容的提问来源于stack exchange,提问作者Syngularity
相关产品推荐
相关产品推荐

