6. Februar 2013 | 2 min lesezeit

Thread-safe Implementierung eines XML-Adapters (JAXB)

Probleme im Zusammenhang mit Multithreading können manchmal auch an eher unerwarteten Stellen auftreten. In diesem konkreten Beispiel war es ein JAXB XML-Adapter, der durch gelegentlich auftretende XML-Mapping-Fehler auffiel. Ist das Problem erst einmal erkannt, dann ist die Lösung aber häufig gar nicht so schwer.

Bei der Implementierung eines JAXB-XML-Bindings ist es gelegentlich notwendig, ein Mapping zwischen den (fachlichen) Objekten und der XML-Repräsentation explizit zu definieren (Grundlagen siehe z.B. [http://weblogs.java.net/blog/kohsuke/archive/2005/09

/using_jaxb_20s.html]).

Das Mapping wird durch eine Klasse realisiert, die von _javax.xml.bind.annotation.adapters.XmlAdapter_ ableitet. Mit Hilfe der Annotation _@XmlJavaTypeAdapter_ wird der Adapter dann in JAXB eingebunden.

Beispiel:

sowie in der verwendenden Klasse:

Bei der Umsetzung des Adapters ist nun darauf zu achten, dass die Implementierung thread-safe erfolgt. Andernfalls kann es zu schwer nachvollziehbaren Fehler kommen.

Im konkreten Fall äußerten sich die Probleme dadurch, dass ein Geburtsdatum, obwohl es Bestandteil der XML-Struktur war, in seltenen Fällen nicht in das Objektmodell übernommen wurde. Erschwerend kam hinzu, dass das Problem innerhalb eines Webservice Frameworks (Apache CXF) und nicht im eigenen Code auftrat.

Glücklicherweise kam relativ schnell der Verdacht auf, dass es sich um ein Problem im Zusammenhang mit parallel ausgeführten Threads handelte und das Problem konnte durch einen kleinen Test, bei dem parallel mehrere XML-Strukturen eingelesen wurden, nachgestellt werden. Ein Blick in das (aus einer XSD generierte) Binding führte dann schnell zu der Klasse _DateAdapter_.

Dort fand sich folgendes:

Das Problem steckte in diesem Fall in der statischen Deklaration des Attributes _format_. Denn die Klasse _SimpleDateFormat_ ist NICHT thread-safe. Ob eine bestimmte Klasse thread-safe ist, lässt sich häufig mit Hilfe von Google relativ schnell beantworten, zumindest wenn sie aus einer oft verwendeten Bibliothek stammt.

Im konkreten Fall eine Lösung zu finden, war nun relativ einfach:

Es gibt selbstverständlich noch andere Lösungen. Die einfachste wäre, in der unmarshal-Methode jeweils eine neue Instanz von SimpleDateFormat zu erzeugen. Bei der konkret verwendeten Implementierung der Bibliothek wäre es auch möglich gewesen, das SimpleDateFormat NICHT static zu definieren, weil bei jeder Verwendung die Klasse DateAdapter neu instanziiert wird. Dies ist jedoch in der Spezifikation nicht vorgeschrieben und somit ist letztere Lösung implementierungsabhängig. Die oben vorgestellte Lösung ist dagegen implementierungsunabhängig und bezüglich der Performance optimiert.

Fazit: Bei der Implementierung eines XML-Adapters sollte man das Thema ‚Multithreading‘ nicht vernachlässigen, da es andernfalls zu schwer nachvollziehbaren Fehlern kommen kann.


Keine Kommentare

Kontakt

OPEN KNOWLEDGE GmbH

Standort Oldenburg:
Poststraße 1, 26122 Oldenburg

Standort Essen:
II. Hagen 7, 45127 Essen