使用jpackage打包Mac应用时签名错误的原因与解决办法
问题:JDK 21 jpackage在Mac Sonoma签名时openssl验证失败?
环境与操作
运行环境:Mac Sonoma 14.3.1,JDK 21
尝试用jpackage打包并签名Java应用的命令:
sudo jpackage \ -i deploy \ -d deploy-mac \ -n "MyApp Name" \ --type app-image \ --main-class "com.my.class.MyClass" \ --main-jar "MyApp.jar" \ --app-version 1.0 \ --copyright "..." \ --description "..." \ --icon "..." \ --vendor "..." \ --mac-app-category "public.app-category.education" \ --verbose \ --mac-sign \ --mac-signing-keychain login \ --mac-signing-key-user-name "XYZ Signing ID"
其中XYZ Signing ID为有效的Apple Developer ID证书标识。
现象
- 省略
--mac-sign、--mac-signing-keychain、--mac-signing-key-user-name三个参数时,打包流程正常完成,但应用无法直接通过Apple Gatekeeper验证。 - 添加签名参数后,
security命令能成功找到证书,但openssl解析临时证书文件失败,核心报错:
unable to load certificate 140704282142656:error:09FFF06C:PEM routines:CRYPTO_internal:no start line:/AppleInternal/Library/BuildRoots/4e1473ee-9f66-11ee-8daf-cedaeb4cabe2/Library/Caches/com.apple.xbs/Sources/libressl/libressl-3.3/crypto/pem/pem_lib.c:694:Expecting: TRUSTED CERTIFICATE
临时证书文件会在jpackage终止前被删除,用--temp参数指定临时目录也无法留存文件。
可能原因及修复/规避方案
1. JDK 21 jpackage的证书格式处理bug
security find-certificate -p导出的证书是DER格式,但jpackage错误地用默认期望PEM格式的openssl x509命令解析,导致验证失败。该问题在JDK 22及后续版本已修复。
规避方案:手动导出PEM格式证书并指定给jpackage
- 导出证书到本地文件:
security find-certificate -c "Developer ID Application: XYZ Signing ID" -a -p login > my-cert.pem - 修改jpackage命令,用
--mac-signing-certificate-file替代--mac-signing-key-user-name:sudo jpackage \ # 保留原有其他参数... --mac-sign \ --mac-signing-keychain login \ --mac-signing-certificate-file ./my-cert.pem
2. sudo导致的keychain权限问题
使用sudo运行jpackage时,root用户的keychain环境与普通用户不一致,可能导致导出的证书文件为空或损坏。
规避方案:
- 取消
sudo,确保当前用户对deploy和deploy-mac目录有读写权限。 - 若必须用
sudo,指定完整的keychain路径而非仅login:--mac-signing-keychain ~/Library/Keychains/login.keychain-db
3. 临时目录权限异常
jpackage自动创建的临时目录权限不足,导致openssl无法读取证书文件。
规避方案:显式指定权限开放的临时目录
mkdir -p /tmp/jpackage-temp chmod 777 /tmp/jpackage-temp sudo jpackage \ # 其他参数... --temp /tmp/jpackage-temp
内容的提问来源于stack exchange,提问作者COTO
相关产品推荐
相关产品推荐

