2009-06-17 5 views
1

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.

Antwort

2

Meine Vermutungen: Sie haben einige Daten Korruption zwischen den beiden Maschinen; oder sie laufen auf verschiedenen Java-Versionen; Sie haben einige knifflige Singletons in der Objektgrafik; Das Reset() auf der Senderseite führt zu Unordnung.

Warum verwenden Sie readUnshared()?

+0

MHarris: Könnten Sie mitteilen, welche der Schätzungen tatsächlich gewonnen wurden? – akarnokd

0

das nie passieren gesehen, und ich benutze Sockets + ObjectStreams ziemlich stark.

Ich schlage vor, Sie versuchen, neuere JVM-Versionen, IllegalStateExceptions tief in den Eingeweiden der Kern-Klasse-Bibliotheken seltsam riechen. Die Tatsache, dass es nur auf einer sehr schnellen Verbindung passiert fast macht es wie eine Race Condition.

Vielleicht haben Sie dieses Mal "einen Fehler in GCC gefunden"?

+0

Wo sehen Sie GCC beteiligt? –

+2

Faire Frage. Das ist ein mehr oder weniger obskurer Verweis auf Programmierer, die denken, dass sie immer Recht haben und etwas anderes schuld ist - OS, Compiler, Hardware. –

+0

Ah, ich verstehe es. Es ist jedoch ebenso dumm (und meiner Erfahrung nach ebenso üblich), sich so an die Infrastruktur (Betriebssystem, Compiler, Hardware) zu "gewöhnen", dass man aufhört, die Möglichkeit in Betracht zu ziehen, dass es kaputt gehen könnte. Fallbeispiel: Bis jetzt habe ich zweimal wiederkehrende JVM-Abstürze in einem Projekt erlebt. Beide Male war es eine Maschine mit fehlerhaftem RAM. –

0

Sieht für mich wie die Netzwerkdaten wird beschädigt.

Kann es einfach sein, dass das kurze Kabel beschädigt ist? Haben Sie versucht, ein anderes kurzes Kabel zu verwenden?

Eine andere Möglichkeit ist eine fehlerhafte Netzwerkkarte oder Treiber.

0

Meine zufällige Schätzung: Obwohl die sendMessage mit synchronized markiert ist, haben Sie mehr als eine Instanz des Objekts für jeden Stream. Oder vielleicht haben Sie mehr als eine ObjectOutputStream für jede SocketOutputStream.