Существует решение для этой проблемы на некоторых форумах OTN (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989).. Но первопричина проблемы не объяснена. Ниже я попытаюсь объяснить первопричину проблемы.
Драйверы Oracle JDBC связываются с сервером Oracle безопасным способом. Драйверы используют класс java.security.SecureRandom для сбора энтропии для защиты связи. Этот класс опирается на встроенную поддержку платформы для сбора энтропии.
Энтропия - это случайность, собранная / сгенерированная операционной системой или приложением для использования в криптографии или других целях, требующих случайных данных. Эту случайность часто собирают из аппаратных источников, будь то аппаратные шумы, аудиоданные, движения мыши или специально предоставленные генераторы случайности. Ядро собирает энтропию и сохраняет ее как пул энтропии и делает случайные символьные данные доступными для процессов или приложений операционной системы через специальные файлы / dev / random и / DEV / urandom .
Чтение из / dev / random истощает пул энтропии с запрошенным количеством битов / байтов, обеспечивая высокую степень случайности, часто желаемую в криптографических операциях. В случае, если пул энтропии полностью истощен и достаточная энтропия недоступна, операция чтения на / dev / random блокируется до тех пор, пока не будет собрана дополнительная энтропия. Из-за этого приложения, считывающие из / dev / random , могут блокироваться в течение некоторого случайного периода времени.
В отличие от вышеизложенного, чтение из / dev / urandom не блокирует. Чтение из / dev / urandom также истощает пул энтропии, но при отсутствии достаточной энтропии он не блокирует, а повторно использует биты из частично прочитанных случайных данных. Говорят, что это подвержено криптоаналитическим атакам. Это теоретическая возможность и, следовательно, не рекомендуется читать из / dev / urandom , чтобы собрать случайность в криптографических операциях.
Класс java.security.SecureRandom по умолчанию считывает данные из файла / dev / random и, следовательно, иногда блокируется в течение произвольного периода времени. Теперь, если операция чтения не возвращается в течение необходимого периода времени, сервер Oracle тайм-аут клиента (в данном случае драйверы jdbc) и прекращает связь, закрывая сокет с его конца. Когда клиент пытается возобновить связь после возврата из блокирующего вызова, клиент обнаруживает исключение ввода-вывода. Эта проблема может возникать случайным образом на любой платформе, особенно если энтропия собирается из аппаратных помех.
Как предлагается на форуме OTN, решение этой проблемы состоит в переопределении поведения по умолчанию java.security.SecureRandom для использования неблокирующего чтения из / dev / urandom вместо блокировки чтения из / dev / random . Это можно сделать, добавив следующее системное свойство -Djava.security.egd = file: /// dev / urandom в JVM. Хотя это хорошее решение для приложений, таких как драйверы JDBC, оно не рекомендуется для приложений, которые выполняют основные криптографические операции, такие как генерация криптографических ключей.
Другие решения могут заключаться в использовании различных реализаций случайных сеялок, доступных для платформы, которые не полагаются на аппаратные шумы для сбора энтропии. При этом вам все равно может потребоваться переопределить поведение по умолчанию java.security.SecureRandom .
Увеличение времени ожидания сокета на стороне сервера Oracle также может быть решением, но побочные эффекты должны быть оценены с точки зрения сервера, прежде чем пытаться это сделать.