In einigen OTN-Foren wird eine Lösung für dieses Problem bereitgestellt (https://kr.forums.oracle.com/forums/thread.jspa?messageID=3699989). Aber die eigentliche Ursache des Problems wird nicht erklärt. Im Folgenden ist mein Versuch, die Ursache des Problems zu erklären.
Die Oracle JDBC-Treiber kommunizieren auf sichere Weise mit dem Oracle-Server. Die Treiber verwenden java.security.SecureRandom Klasse zum Sammeln von Entropie zum Sichern der Kommunikation. Diese Klasse stützt sich auf die native Plattformunterstützung zum Sammeln der Entropie.
Entropie ist die Zufälligkeit, die von einem Betriebssystem oder einer Anwendung zur Verwendung in der Kryptografie oder anderen Anwendungen, die zufällige Daten erfordern, gesammelt/erzeugt wird. Diese Zufälligkeit wird oft von Hardwarequellen gesammelt, entweder von Hardwaregeräuschen, Audiodaten, Mausbewegungen oder speziell bereitgestellten Zufallsgeneratoren. Der Kernel sammelt die Entropie und speichert sie in einem Entropiepool und stellt die zufälligen Zeichendaten den Prozessen oder Anwendungen des Betriebssystems über die speziellen Dateien /dev/random zur Verfügung und /dev/urandom .
Lesen von /dev/random entleert den Entropiepool mit der angeforderten Menge an Bits/Bytes, wodurch ein hohes Maß an Zufälligkeit bereitgestellt wird, das häufig bei kryptografischen Operationen erwünscht ist. Falls der Entropiepool vollständig geleert ist und nicht genügend Entropie verfügbar ist, wird der Lesevorgang auf /dev/random blockiert, bis zusätzliche Entropie gesammelt wird. Aus diesem Grund lesen Anwendungen aus /dev/random kann für einen zufälligen Zeitraum blockieren.
Im Gegensatz zu oben liest man aus /dev/urandom blockiert nicht. Lesen von /dev/urandom entleert ebenfalls den Entropiepool, aber wenn nicht genügend Entropie vorhanden ist, blockiert es nicht, sondern verwendet die Bits aus den teilweise gelesenen Zufallsdaten wieder. Diese soll anfällig für kryptoanalytische Angriffe sein. Dies ist eine theoretische Möglichkeit und daher wird davon abgeraten, aus /dev/urandom zu lesen Zufälligkeit in kryptografischen Operationen zu sammeln.
Die java.security.SecureRandom Klasse liest standardmäßig aus /dev/random Datei und blockiert daher manchmal für einen zufälligen Zeitraum. Wenn nun der Lesevorgang für eine erforderliche Zeitspanne nicht zurückkehrt, überschreitet der Oracle-Server das Zeitlimit für den Client (in diesem Fall die jdbc-Treiber) und bricht die Kommunikation ab, indem er den Socket an seinem Ende schließt. Wenn der Client versucht, die Kommunikation fortzusetzen, nachdem er von dem blockierenden Aufruf zurückgekehrt ist, trifft er auf die IO-Ausnahme. Dieses Problem kann zufällig auf jeder Plattform auftreten, insbesondere dort, wo die Entropie aus Hardwaregeräuschen gewonnen wird.
Wie im OTN-Forum vorgeschlagen, besteht die Lösung für dieses Problem darin, das Standardverhalten von java.security.SecureRandom zu überschreiben Klasse, um das nicht blockierende Lesen von /dev/urandom zu verwenden anstelle des blockierenden Lesens von /dev/random . Dies kann durch Hinzufügen der folgenden Systemeigenschaft -Djava.security.egd=file:///dev/urandom erfolgen zur JVM. Obwohl dies eine gute Lösung für Anwendungen wie die JDBC-Treiber ist, wird davon für Anwendungen abgeraten, die kryptografische Kernoperationen wie die Generierung kryptografischer Schlüssel ausführen.
Andere Lösungen könnten darin bestehen, verschiedene zufällige Seeder-Implementierungen zu verwenden, die für die Plattform verfügbar sind und nicht auf Hardwarerauschen zum Sammeln von Entropie angewiesen sind. Damit müssen Sie möglicherweise immer noch das Standardverhalten von java.security.SecureRandom überschreiben .
Das Erhöhen des Socket-Timeouts auf der Seite des Oracle-Servers kann ebenfalls eine Lösung sein, aber die Nebeneffekte sollten aus Serversicht bewertet werden, bevor Sie dies versuchen.