Ich arbeite an einem verteilten System, das auf RMI basiert mit jdk1.6.
Gelegentlich kann ConcurrentModificationException
Fehler in diesem Thread innerhalb der RMI-Laufzeit auftreten, wenn Objekte nicht serialisiert werden können. Ich kann diese Ausnahme leicht reproduzieren, indem ich gleichzeitig das von der Remote-Methode zurückgegebene Objekt aktualisiere.
Aber das Problem ist, dass ich die Quelle dieser Anrufe nicht finden kann. Die RMI-Ausnahme wird in stderr
geschrieben (wird auf der Serverseite innerhalb des Laufzeitcodes erfasst, nachdem sie die Remote-Objektmethode beendet hat), aber es gibt keine übereinstimmende Ausnahme in den Client-Diensten (wenn dies ein legitimer Remote-Aufruf wäre, würde RemoteException
mit entsprechender Ursache) erhoben werden).
Die einzige Ausnahme bei diesen Ausnahmen ist, dass sie im "RMI TCP Connection (idle)" Thread und nicht in einem Thread wie "RMI TCP Connection (& lt; Verbindungsanzahl & gt;) - & lt; Client Endpunktinfo & gt;" .
Irgendwelche Hinweise darauf, was diese "Leerlauf" -Threads in RMI sind? Ich habe es nicht gefunden in den openjdk Quellen.
Upd: Ich füge einen Exception-Stack-Trace hinzu, wie er reproduziert wird, was man normalerweise in der beschriebenen Situation sieht.
Serverseitige Konsole zeigt:
%Vor%Ausnahmebedingung für Clientgröße an Aufrufer:
%Vor%Ich bin auf den Grund gegangen. Problem tritt in zwei Fällen auf:
UnicastServerRef
versucht die Ursache in den (bereits beschädigten) Rückstrom zu schreiben und verursacht ConcurrentModificationException
. ConcurrentModificationException
(oder einer anderen Laufzeitausnahme) serialisiert werden kann. Exception dispatching call to
-Zeile). Das erklärt, dass der Name des Threads inaktiv ist, da er bereits aus RMI-Sicht in den Pool zurückgegeben wird. Hier ist die wirkliche Ausnahme, die tatsächlich etwas anders ist als die reproduzierte Ausnahme in Bezug auf die erste Zeile und den tatsächlichen Aufruf-Trace:
%Vor% Es gibt nicht viele Hinweise auf das ursprüngliche Problem, also muss ich auf eine Client-Ausnahme warten, die irgendwann erscheint, um das Problem zu beheben.
Wenn diese Art von Ausnahme beim Lesen des JMX-Attributs durch jconsole auftritt, wird StackTrace nicht angezeigt, aber der Attributwert wird als Nicht verfügbar angezeigt.
Threads werden im RMI-Verbindungspool mit dem Namen 'RMI TCP Connection (idle)' erstellt. Wenn einer davon verwendet wird, benennt der ausführbare Runnable den Thread in 'RMI TCP Connection (n)' um, wobei n
die Nummer der Verbindung ist, die bearbeitet wird (eine fortlaufende Nummer), und wird wieder in 'idle' umbenannt. im Runnable ist endlich Block. Jede Spur mit der Bezeichnung "RMI TCP Connection (idle)" muss daher vor dem Runnable stehen und sie als Verbindungsthread umbenennen oder umbenennen, nachdem sie umbenannt wurde.
Frag mich nicht, wie das möglich ist. Die eigentliche Antwort auf Ihr Problem, wenn nicht Ihre Frage, ist es nicht, Objekte zu ändern, während sie gleichzeitig zurückgegeben werden; -)