Frage

Wir erleben ein überaus schwer aufzuspüren Problem, bei dem wir sehen Classcastexceptions manchmal , wenn eine Liste von entordnet Objekten zu iterieren versuchen. Das wichtige Bit ist manchmal , nach einem Neustart der jeweilige Code funktioniert gut. Dies scheint die Richtung der Parallelität / Timing / Race-Bedingung zu weisen. Ich kann bestätigen, dass weder die JAXBContext, noch die Einweiser und unmarshallers gleichzeitig verwendet werden. Wir haben so weit gegangen, wie der Zugang zu ihnen Serialisierung durch Sperren.

Da wir jedoch auf einer OSGi-Plattform laufen, wo einzelne Bündel asynchron über Feder DM initialisiert werden immer kann es sein, dass zwei unterschiedliche Bündel ihre JAXBContext zugleich schaffen.

Auf jedem Fall würde ich irgendwelche Hinweise auf eine Erklärung zu schätzen wissen, was dazu führen könnte, diese intermittierend Classcastexceptions. Die intermittierende ist wichtig, da sie zeigen, dass der Code selbst normal arbeitet gut, aber dass einige externe Faktor scheint das Verhalten zu beeinflussen.

Hier ist ein konkretes Beispiel für die Ausnahme ist (man beachte ich das Unternehmen spezielle Sachen entfernt):

Caused by: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.foobar.TunnelType
    at com.foobar.NetMonitorImpl.getVpnStatus(NetMonitorImpl.java:180)

Das Verfahren bei der Linie 180 ist eine für () -Konstrukt innerhalb eines entordnet Objekt über eine Sammlung von Objekten TunnelType Looping (sagte unmarshalling BTW funktioniert gut).

Da das eigentliche Objekt unmarshalling ging gut, ist es auch physisch möglich für JAXB ElementNSImpl Objekte innerhalb von verschachtelten Sammlungen zu verlassen?

Laufzeitumgebung:

  • JAXB 2.1
  • OSGi
  • Feder DM
  • Die JAXBContext mit dem Classloader des Bündels initialisiert die Klassen, die vermarshallten / entordnet
  • werden
War es hilfreich?

Lösung 3

Aus Verzweiflung wandten wir uns auf dem JAXBContext.class Objekt zu synchronisieren, sehen dies als die einzige für einige Rennen Zustand verbleibende Möglichkeit und zumindest haben wir nicht in der Lage gewesen, wieder um dieses Problem zu reproduzieren. Hier ist der kritische Code:

synchronized (JAXBContext.class) {
    context = JAXBContext.newInstance(packageList, classLoader);
}

Andere Tipps

Ich erhalte diese Ausnahme nur, wenn ich vergessen JAXBContext zu sagen, über ALL zu-vermarshallten Typen es mit zu tun könnte.

JAXBContext.newInstance(MyClass1.class,MyClass2.class, [...]);

Keiner der Ansätze vorgeschlagen, hier hat es für mich. Allerdings löste dieses mein Problem

@XmlAnyElement(lax = true)
public List<Foo> foos;

Die synchronisierte Klausel oben löste das Problem für mich als gut, aber es scheint, wie der Kontext nicht eine lokale Variable sein sollte. Stattdessen sollte es eine Instanzvariable oder eine statisch sein. Ich war nicht in der Lage, meinen Code Refactoring, wie ich es möchte, so stattdessen zog ich den Kontext in einen statischen Initialisierer, die nicht perfekt ist, aber scheint zu funktionieren:

 private static Unmarshaller um;

  static{
    try {
      final JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
      um = ctx.createUnmarshaller();
    } catch (final JAXBException e) {
      e.printStackTrace();
    }
  }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top