lange Strings senden

Status
Nicht offen für weitere Antworten.

muge

Mitglied
Hallo zusammen.

Die Zeile 3 des folgenden Codeschnipsels wirft manchmal eine Exception:
java.lang.ArrayIndexOutOfBoundsException: 256

Code:
socket = new Socket(ip, port);
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(msg.toString());

msg ist ein Objekt, welches eigentlich nur eine Datenstruktur ist (mit get/set Methoden).

Die Zeile hat schon unzählige solche msg Objekte versandt, ohne Probleme. Erst seit kurzem passiert manchmal die genannte Exception, bis jetzt nur dann, wenn die msg einen StackTrace enthält, welcher zu einem String zusammengehängt wurde. Grundsätzlich macht dies aber keine Probleme.

Derzeit kann ich den Fehler nicht gezielt Reproduzieren :? , das heisst mit debugging wird nichts.

Strings mit bis zu 20000 Zeichen können ohne Probleme verarbeitet werden. Die msg's, welche diese Exception auslösen, sind wesentlich kürzer.

Hat jemand eine idee, wie wo und warum diese Exception ausgelöst wird? Was bedeutet eine ArrayIndexOutOfBoundsException bei writeObject()?

thx
muge
 
warum machst du writeObject?

und dann msg.toString?

schick doch msg selbst (sofern serialisierbar), writeUTF oder verwende einen Writer um einen String zu verschicken?

wird vielleicht oft der gleiche String geschickt? schau mal die API doc zu writeUnshared an...
 
Ich weiss nicht mehr genau, weshalb ich writeObject den Vorzug vor writeUTF gegeben habe. Das senden des objektes habe ich deshalb nicht gemacht, weil der auswertende Prozess nicht unbedingt Java sein soll, auch wenn er es derzeit ist.

Im msg Objekt werden informationen zum loggen transportiert. es wird nie zweimal der gleiche String geschickt.
 
muge hat gesagt.:
Ich weiss nicht mehr genau, weshalb ich writeObject den Vorzug vor writeUTF gegeben habe. Das senden des objektes habe ich deshalb nicht gemacht, weil der auswertende Prozess nicht unbedingt Java sein soll, auch wenn er es derzeit ist.

Im msg Objekt werden informationen zum loggen transportiert. es wird nie zweimal der gleiche String geschickt.

Puu, die andere Seite nicht in Java??

in dem fall würde ich rohe bytes senden, damit keine verwirrung mit dem encoding entsteht (das müsste man in diesem Fall fixieren)
 
writeObject ruft über eine Methode writeString die writeByte Methode auf. Habe ich im StackTrace gesehen.

Ich weiss einfach nicht, woher die Exception kommt und wieso.
 
Eigentlich werden ja immer Bits gesendet...

Ich habe aber nicht das Problem dass ich die Daten nicht lesen kann. Mein Problem ist dass manchmal eine ArrayIndexOutOfBoundsException geworfen wird, die ich nicht reproduzieren kann und keine Ahnung habe, wieso sie geworfen wird.
 
ich auch nicht

ist am string irgendwas besonderes?

sonderzeichen?

ich würde trotzdem drauf tippen, dass da irgendwas mehrfach geschickt wird (und der objectstream mit seinen back-referenzen durcheinander ist...)
 
Nein, nichts besonderes. das besonderste Zeichen ist ein "$". Es funktioniert auch in 99% aller Fälle und in diesen Fällen sind die Daten korrekt.

Der String der übermittelt wird sieht so aus:

1116414101507 -1 0 0 DEPRECATED LOG ENTRY:0:A IOException occured, Exception is: java.net.ConnectException: Connection refused: connect StackTrace: java.net.PlainSocketImpl.socketConnect(Native Method) java.net.PlainSocketImpl.doConnect(Unknown Source) java.net.PlainSocketImpl.connectToAddress(Unknown Source) java.net.PlainSocketImpl.connect(Unknown Source) java.net.SocksSocketImpl.connect(Unknown Source) java.net.Socket.connect(Unknown Source) java.net.Socket.connect(Unknown Source) ch.retis.wms4.common.interprocesscom.Ipc.connect(Ipc.java:52) ch.retis.wms4.common.interprocesscom.Ipc.syncSend(Ipc.java:84) ch.retis.wms4.common.interprocesscom.IpcClient.send(IpcClient.java:51) ch.retis.wms4.client.masterconsole.JobDetailsProxy.getUptime(JobDetailsProxy.java:42) ch.retis.wms4.client.masterconsole.ObjectArrayWindow.getProcessMessage(ObjectArrayWindow.java:79) ch.retis.wms4.client.masterconsole.ObjectArrayWindow.getNewProcessUpdate(ObjectArrayWindow.java:90) ch.retis.wms4.client.masterconsole.ObjectArrayWindow.access$2(ObjectArrayWindow.java:87) ch.retis.wms4.client.masterconsole.ObjectArrayWindow$2.run(ObjectArrayWindow.java:62) java.util.TimerThread.mainLoop(Unknown Source) java.util.TimerThread.run(Unknown Source)

Die Linefeeds sind zur besseren Lesbarkeit eingefügt worden, sind aber nicht im übertragenen String
 
is aber nicht der string, sondern seine serialisierte version; ist zwar egal...

wieviele strings schreibst du eigentlich in den Stream? immer nur eins??
 
Das ist der String.
Der StackTrace wird in einen String verwandelt und der wird hinten an die zusätzlichen Daten (ebenfalls Strings) angehängt. Als Trennzeichen werden Tabulatoren verwendet. Das Stringende ist ein Linefeed (solche Fehler merkt aber nur der Empfänger)

Es werden mehrere Strings in den Stream geschrieben. nach jedem schreiben wird der Stream geflusht.

Hat der ObjectStream einen Buffer?
 
Jetzt kommt noch eine Plattformabhängigkeit hinzu. Unter Linux und Netbeans bringe ich den Fehler gar nicht mehr zustande. Mit Eclipse und windows ist er ziemlich regelmässig :?
 
Note that there is a significant difference between writing a String into the stream as primitive data or as an Object. A String instance written by writeObject is written into the stream as a String initially. Future writeObject() calls write references to the string into the stream.
 
Ok, habe es jetzt mal gewechselt. writeUTF(). gebracht hat es aber nicht wirklich viel. Anstelle der Exception blockiert es nun beim schreiben. Wie bei C, wenn der andere Prozess nicht liest...
 
Wichtig ist, das Du den Stream, nachdem du reingeschrieben hast erstmal schließt, sonst kann der Lesende nicht drauf zugreifen. Da gibt es bei Strings immer Probleme
 
ich will den Stream nicht schliessen, weil ich nicht für jede Message die Verbindung neu aufbauen will und schliessen des streams bewirkt ein schliessen des Sockets.

Ausserdem, es funktioniert ja alles, bis auf ganz wenige ausnahmen und die muss ich auch noch in den griff kriegen.
 
Das Problem ist gelöst. Die Klasse, welche die nachricht sendet, ist statisch und es haben mehrere Threads darauf zugegriffen. Da gab es offenbar unterbrüche durch den Scheduler an ungünstigen stellen :-/.
Ich habe den kritischen Teil jetzt synchronized gemacht und es läuft wie gewünscht.

Was ich weiterhin etwas seltsam finde ist, dass der Fehler unter Linux nicht aufgetreten ist. Als würde die VM für Linux das ganze bereits Threadsafe behandeln und die VM von Windows nicht.

Danke für die Hilfe.
cu
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben