带有jlink的SSLHandshakeException创建的运行时

ric*_*ich 6 java jlink java-11

我有一个dropwizard应用程序,可以在标准JRE上正常运行。

我尝试使用jlink创建一个运行时,该运行时小得多:

/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/bin/jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.scripting,java.security.jgss,java.sql,java.xml,jdk.attach,jdk.jdi,jdk.management,jdk.unsupported --output jre
Run Code Online (Sandbox Code Playgroud)

如果我使用创建的jlink运行时来运行它,则会引发连接到redis的错误(它的前面有通道)。

ERROR [2019-03-31 09:12:20,080] com.company.project.core.WorkerThread: Failed to process message.
! javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
! at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
! at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
! at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
! at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Unknown Source)
! at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
! at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(Unknown Source)
! at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(Unknown Source)
! at redis.clients.jedis.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:52)
! at redis.clients.jedis.util.RedisOutputStream.flush(RedisOutputStream.java:133)
! at redis.clients.jedis.Connection.flush(Connection.java:300)
! ... 9 common frames omitted
! Causing: redis.clients.jedis.exceptions.JedisConnectionException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
! at redis.clients.jedis.Connection.flush(Connection.java:303)
! at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:235)
! at redis.clients.jedis.BinaryJedis.auth(BinaryJedis.java:2225)
! at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:119)
! at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:888)
! at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:432)
! at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361)
! at redis.clients.jedis.util.Pool.getResource(Pool.java:50)
! ... 2 common frames omitted
! Causing: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
! at redis.clients.jedis.util.Pool.getResource(Pool.java:59)
! at redis.clients.jedis.JedisPool.getResource(JedisPool.java:234)
Run Code Online (Sandbox Code Playgroud)

stunnel服务器日志显示:

redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG7[23]: TLS alert (write): fatal: handshake failure
redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG3[23]: SSL_accept: 141F7065: error:141F7065:SSL routines:final_key_share:no suitable key share
redis_1  | 09:12:20 stunnel.1 | 2019.03.31 09:12:20 LOG5[23]: Connection reset: 0 byte(s) sent to TLS, 0 byte(s) sent to socket
Run Code Online (Sandbox Code Playgroud)

jlink是否遗漏了一些加密算法?

小智 8

正如评论中提到的那样

嗯 如果我添加jdk.crypto.ec,则可以正常工作-为什么jdeps会遗漏一个,如果那个遗漏,还会有其他遗漏吗?

将jdk.crypto.ec添加到模块列表中可以解决此问题。

  • 因此,您可以 jlink 一个具有 HTTPS 支持的完美运行时,但没有任何 SSL/TLS/... 实现,并且仅在握手失败时注意到一条错误消息... 令人困惑。我明白为什么会发生这种情况,但这肯定不方便,也不遵循最小意外原则。 (3认同)
  • 这是非常令人沮丧的,这就是解决办法。我的应用程序在 JRE 上部署了几个月,然后它突然失去了与我的服务器通信的能力(这意味着没有更新)。他们为什么不只包括这个。 (2认同)

mip*_*ipa 6

还可以将--bind-services(服务提供者模块中的链接及其依赖项)添加到 jlink 命令。但根据我的经验,这将使结果运行时间更大。但至少这是一个选项,可以快速找出观察到的问题是否是由于缺少 Service 实现造成的。


Luk*_*cek 5

添加requires jdk.crypto.ec;到 module-info.java 中为我解决了这个问题。