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

Spring-Kotlin应用打包exe后出现SSLHandshakeException的原因及解决

问题

我有一个Spring-Kotlin独立应用,直接运行应用或启动jar包时一切正常,可正常连接Supabase PostgreSQL数据库。但使用以下jpackage脚本生成exe并运行时:

commandLine(
       "$javaHome/bin/jpackage",
       "--type", "app-image",
       "--input", "build/libs",
       "--main-jar", jarPath,
       "--name", appName,
       "--dest", outputDir,
       "--app-version", version.toString(),
       "--icon", "src/main/resources/car_icon.ico",
       "--java-options", "-Djava.awt.headless=false",
       "--java-options", "-Dlogging.file=app.log",
       "--resource-dir", "src/main/resources",
       "--runtime-image", layout.buildDirectory.dir("my-runtime").get().asFile.absolutePath
   )

出现如下错误:

Caused by: org.postgresql.util.PSQLException: SSL error: Received fatal alert: insufficient_security
        at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:53)
        at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:631)
        at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:201)
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:268)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
        at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:273)
        at org.postgresql.Driver.makeConnection(Driver.java:446)
        at org.postgresql.Driver.connect(Driver.java:298)
        at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:137)
        at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:360)
        at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:202)
        at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:461)
        at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:550)
        at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:98)
        at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:111)
        at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:126)
        at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:46)
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:126)
        ... 146 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: insufficient_security
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:365)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:204)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
        at org.postgresql.ssl.MakeSSL.convert(MakeSSL.java:51)
        ... 163 more

为何仅运行exe时会出现该错误?该如何解决?

原因分析

核心问题是jpackage使用的自定义runtime镜像缺少SSL加密所需的关键组件。直接运行jar时依赖完整的JDK/JRE,包含所有默认安全提供者和加密套件;但通过--runtime-image指定的自定义运行时镜像,在构建过程中可能被自动裁剪掉了SSL/TLS相关的必要模块或加密算法,导致无法满足Supabase PostgreSQL要求的安全级别,从而触发insufficient_security错误。

解决方法

1. 确保自定义runtime包含完整安全模块

使用jlink构建runtime时,显式添加SSL相关的核心模块,避免被裁剪:

jlink --add-modules java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.xml.crypto \
      --output my-runtime \
      --strip-debug \
      --no-man-pages \
      --no-header-files

其中java.security.jgss和java.xml.crypto是SSL加密的关键依赖模块,必须包含。

2. 添加Java安全参数指定兼容的SSL配置

在jpackage的--java-options中添加SSL相关参数,强制使用Supabase支持的协议和加密套件:

commandLine(
       // ... 保留原有参数
       "--java-options", "-Djava.awt.headless=false",
       "--java-options", "-Dlogging.file=app.log",
       "--java-options", "-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3",
       "--java-options", "-Djavax.net.ssl.trustStore=${System.getProperty("java.home")}/lib/security/cacerts"
   )

Supabase PostgreSQL默认支持TLSv1.2和TLSv1.3,显式指定可避免协议不匹配问题。

3. 更新PostgreSQL JDBC驱动版本

确保使用最新版本的PostgreSQL驱动(推荐42.6.x及以上),旧版本可能存在与新版JDK runtime的SSL兼容问题。在build.gradle.kts中更新依赖:

implementation("org.postgresql:postgresql:42.6.0")

4. 验证runtime的安全配置

检查自定义runtime镜像中lib/security/java.security文件,确认以下安全提供者配置存在:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider

缺少这些配置会导致无法加载必要的加密算法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:15:07