Ich habe zwei Anwendungen laufen auf zwei verschiedenen Maschinen, die kommunizieren, indem Serializable "Message" Objekte über Javas Socket-Implementierung zu senden. Jeder schafft eine Socket, eine Verbindung zu dem anderen Server und dann die folgenden Bits (pseudo-Java, Fehler- und Verbindungsdetails der Kürze elided):Sockets und ObjectInputStreams
Code empfangen:
while (true) {
Object received = oisFromOtherMachine.readUnshared();
dispatch(received);
}
Code gesendet:
synchronized void sendMessage(Message m) {
oosToOtherMachine.writeObject(m);
oosToOtherMachine.flush();
oosToOtherMachine.reset();
}
Das wird ziemlich regelmäßig aus einer Vielzahl von verschiedenen Threads aufgerufen.
Das alles funktionierte gut und dandy bis vor etwa 3 Wochen, wo manchmal als Reaktion auf eine bestimmte Benutzereingabe, der Aufruf an readUnshared werfen wird. Bis jetzt haben wir "java.lang.IllegalStateException: ungelesene Blockdaten" und "java.lang.ClassCast Ausnahme: java.util.HashMap kann nicht in java.io.ObjectStreamClass umgewandelt werden", beide von tief in den Interna von ObjectInputStream.
Es passiert ungefähr einmal in 5, normalerweise, nachdem die zwei Systeme oben gewesen sind und für 15+ Minuten miteinander sprechen. Aus verschiedenen Gründen haben wir zwei Netzwerkkabel, die regelmäßig zwischen den beiden verwendet werden, ein Knarled und verknotete 15m (Ping von 30ms +), der andere etwa 1m (Ping von < 1ms). Es ist nur über das kurze Kabel passiert (und glauben Sie mir, wir haben es oft über den langen versucht).
Ich habe versucht zu überprüfen, alles, was von jedem Message-Objekt erreichbar ist Serializable, keine Hinweise in den Protokollen für beide App, bevor die Nachricht gesendet wird, und die App, die den Fehler nicht weiter geht fröhlich weiter auf ihrem Weg, nicht bewusst Probleme.
So. Google schlägt keine Fälle in OIS, OOS oder Java Sockets vor, die dazu führen könnten, dass meine Kollegen so ratlos sind wie ich ... Hat jemand schon einmal so etwas gesehen?
Bearbeiten: Vielen Dank für Anregungen jeder. (-: Zusammenfassend vermute ich, dass ein unsynchronisierter Zugriff auf einige der Logging-Status-Objekte ein beschädigtes Objekt-Diagramm erzeugt, das OIS zum Ersticken bringt. Dies muss jedoch gestern gelöst werden, und eine liberale Anwendung des synchronisierten Schlüsselworts zusammen mit dem Folgenden Gräuel ...
try {/* message loop */ } catch (RuntimeException) { /* resync appstate and continue*/ }
... werden viel schneller und mit deutlich höheren Erfolgschancen als frustrierend (25min +) erfolgen versucht, das Problem & zugeordnet headscratching zu reproduzieren.
MHarris: Könnten Sie mitteilen, welche der Schätzungen tatsächlich gewonnen wurden? – akarnokd