SSLHandshakeException с созданной средой выполнения jlink

У меня есть приложение 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

Если я запускаю его со средой выполнения, созданной jlink, он выдает эту ошибку при подключении к Redis (перед которым стоит stunnel).

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)

Журналы сервера 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

Есть ли какие-то алгоритмы шифрования, которые не учитывает jlink?

Хм. Если я добавлю jdk.crypto.ec, это сработает - почему jdeps упустили это, если это, будут ли другие, которые он не учел?

rich 31.03.2019 11:45

Кажется, я припоминаю, что поставщики JCA являются расширениями: ничто в библиотеке не зависит от них напрямую, они должны быть явно помещены в путь к классам (как и другие типичные расширения адаптера: соединители базы данных и т. д.)

jjmontes 31.03.2019 11:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
27
2
2 436
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Как Рич упоминает в комментарий

Hmmn. If I add jdk.crypto.ec it works - why would jdeps have left that one out, if that one, would there be any others it's left out?

добавление jdk.crypto.ec в список модулей решило проблему.

Таким образом, вы можете связать совершенно хорошую среду выполнения с поддержкой HTTPS, но без какой-либо реализации SSL/TLS/... и заметить только, когда рукопожатие завершается сбоем с сообщением об ошибке, которое... запутывает. Я понимаю, почему это происходит, но это определенно не удобно и не следует принципу наименьшего удивления.

Hendrik 03.10.2019 18:18

Это очень расстраивает, это было исправление. Мое приложение было развернуто в течение нескольких месяцев на JRE, а затем оно внезапно потеряло способность общаться с моим сервером (что означает отсутствие обновлений). Почему бы им просто не включить это.

Mgamerz 25.01.2020 18:56

В OpenJDK 11.0.9/Win64 это увеличивает размер JRE на 0.3 MiB.

lapo 23.10.2020 15:46

Отмечая для поисковых систем, что он также исправляет ошибку Received fatal alert: access_denied

Asapha 02.09.2021 11:28

Можно также просто добавить --bind-services (Ссылка в модулях поставщика услуг и их зависимостях) к команде jlink. Но, согласно моему опыту, это значительно увеличит время выполнения. Но, по крайней мере, это возможность быстро выяснить, не связаны ли наблюдаемые проблемы с отсутствующей реализацией Сервиса.

Добавленный requires jdk.crypto.ec; в module-info.java устранил проблему для меня.

Это сработало для моего варианта использования сегодня. Я получал ошибки DEADLINE_EXCEEDED при использовании клиентской библиотеки GCP Java. Это произошло примерно через 10 секунд, поэтому я предположил, что это какая-то внутренняя ошибка, которая заставляла gRPC повторять попытки до истечения крайнего срока. К сожалению, сообщение об ошибке в исключении, сгенерированном через 10 секунд, бесполезно. Трассировка стека и причина закончились на «ошибке асинхронной задачи» или что-то в этом роде. Во время отладки я заметил исключение, связанное с SSL, выдаваемое gRPC. Добавление этого модуля в мою среду выполнения jlink остановило это исключение.

Matt Welke 11.10.2021 21:51

Пришлось еще добавить jdk.crypto.ec и jdk.crypto.cryptoki.

Другие вопросы по теме