logo Red Star Development

donderdag 22 maart 2018

Xb4j: de Kadaster casus

Het moet een late vrijdagmiddag zijn geweest, eind augustus 2017. De exacte datum weet ik niet meer. Ik zit naast Mando, de consultant die we hebben ingehuurd om onze JAXB-kennis te versterken. Ik kijk toe hoe hij behendig met zijn debugger door de JAXB-broncode stapt. We onderzoeken al de hele middag hoe we om de bug heen kunnen werken. Verschillende ideeën zijn opgekomen, maar niet één die ons heeft overtuigt de juiste te zijn. Eigenlijk geloof ik er niet meer in dat JAXB voor dit project de juiste oplossing is. Niet met de voorwaarden die we hebben gesteld: geen code duplicatie. Niet in de gegenereerde Java klassen, maar ook niet in de Java code die de transformatie verzorgt.

Mijn geloof zit deze week in een vrije val. Begin november stopt het Kadaster met de levering van hun SOAP bericht Kik-inzage versie 4.7. We hebben nog maar twee maanden om onze software om te schrijven en hun nieuwe versie 5.1 te gebruiken. Nog twee maanden! We zijn nu twee maanden bezig en maken veel te weinig voortgang; we hebben een technologische keuze gemaakt (JAXB versus XSLT), en zijn begonnen met de implementatie. That’s it. En dan lopen we ook nog tegen die blokkerende bug aan in JAXB. Lukt het niet om begin november klaar te zijn, dan zullen de Gemeentelijke Sociale Diensten, onze klanten, geen kadastrale gegevens van ons krijgen, die ze nodig hebben voor de beoordeling van aanvragen voor bijstandsuitkeringen. Het zou een groot gezichtsverlies betekenen voor ons bedrijf.

Ik zucht en haal nog een rondje koffie. Als iedereen zijn drankje heeft, keer ik achter mijn eigen bureau terug. Ik mompel tegen Mando dat ik nog even iets wil uitzoeken. In werkelijkheid wil ik verder met mijn proof of concept waar ik een paar dagen geleden aan begonnen ben. Voor het Kik-inzage bericht, maar dan met een andere techniek: XB4J. Een kleine, open source bibliotheek die net als JAXB bedoeld is om XML naar Java om te zetten en vice versa. Ik heb het een aantal jaar geleden zelf ontwikkeld. Het is gespecialiseerd in de problematiek waar we nu met JAXB door een bug gestopt worden. Ik weet dat het met XB4J moet kunnen, maar ik weet ook dat er tijd in geïnvesteerd moet worden, zodat het de complexiteit van het Kadaster bericht ondersteunt. En ik was er niet aan toe om mijn vrije tijd hieraan te wijden. Maar ik zie geen alternatieven meer.

Het duurt niet lang of ik zit in een flow. In Eclipse heb ik de Java klasse openstaan waarin ik programmeer hoe XB4J de Java representatie koppelt aan de XML-representatie, het zogenaamde ‘binding model’. Veel informatie die we van Kadaster geleverd krijgen, gebruiken we niet. Met een Ignore-binding vertel ik dit aan XB4J. Voor de proof of concept gebruik ik voor elke XML-entiteit even de Ignore-binding, om de structuur snel gemodelleerd te hebben. Daarna kan ik verfijning aanbrengen en één voor één de entiteiten die we nodig hebben aan Java representaties van de XML koppelen. Het is een monnikenwerk en ik begrijp de charme van JAXB wel. Voor de drie Kadaster operaties heeft JAXB binnen drie seconden de meer dan 1500 klassen gegenereerd die het denkt nodig te hebben. JAXB genereert veel klassen dubbel vanwege de manier waarop het Kadaster met zijn XML namespaces omgaat. Door de bug in JAXB lukt het niet om in alle constructies die Kadaster hanteert, de dubbelen betrouwbaar terug te brengen. Met als resultaat dat tijdens het ummarshallen van een bericht gegevens verloren gaan, zonder dat er een foutmelding optreedt.

Ik denk dat we met XB4J slechts een vuistvol Java klassen nodig hebben om de informatie vast te leggen die we van het Kadaster nodig hebben. XB4J genereert ze niet, als ontwikkelaar moet je die zelf schrijven. Voor de proof of concept wil ik de NatuurlijkPersoon klasse schrijven en deze koppelen aan de twee XML-representaties die in de eerste operatie van het Kadaster-bericht voorkomen. Ze komen ook nog twee keer voor in de twee andere operaties, maar daar hergebruik ik dezelfde NatuurlijkPersoon klasse. We moeten wel telkens weer de bindingmodel vertellen dat deze Java klassen ook gekoppeld moeten worden aan elementen in andere XML namespaces. Het zou lekker zijn als er tooling was, die ondersteunde bij het maken van het binding model. Een tool die de WSDL of XML-schema zou lezen en waarmee je via een GUI kunt aangeven hoe de XML elementen gekoppeld moeten worden aan welke Java klassen en attributen. Dat zou het werken met XB4J een stuk prettiger maken. Maar die tooling moet nog geschreven worden.

De maandag daarna, op de laatste dag van de sprint, kan ik de proof of concept aan het team presenteren. Ik heb in het weekeinde gewerkt om XB4J aan te passen, zodat de constructie met ‘unbounded choices’ in het kadaster bericht ondersteund wordt. Via een geautomatiseerde test kan ik laten zien dat een XML bericht naar een Java representatie wordt omgezet en weer terug naar XML. Er gaan geen gegevens verloren, zoals dat wel het geval is met JAXB. Mijn beide collega ontwikkelaars zijn kritisch, maar enthousiast. Ook Mando heeft het weekeinde nuttig besteed en heeft een oplossing gevonden waarmee om het probleem in JAXB heen gewerkt kan worden. Zijn aanpak grijpt in op het unmarshall-proces: het verandert de namespace van de XML-elementen die problemen geven, in de namespace variant die voor dat element geen probleem geeft, voordat JAXB ze omzet naar Java instanties. Het vereist het vastleggen in de code van alle namespaces en element combinaties die problemen geven.

‘s Middags bespreken we met het hele team de voor- en nadelen van JAXB en XB4J, en spreken we uit in welke techniek we het meest vertrouwen hebben om het nieuwe Kadaster bericht te implementeren. Na een levendige discussie kan iedereen zich vinden in een keuze voor XB4J. De doorslag wordt gegeven door de volgende argumenten:

  1. XB4J koppelt de Java representatie los van het XML-schema, waardoor hergebruik van de Java code (en alles wat daarvan afhankelijk is, zoals transformaties etc.) makkelijker te realiseren is. Het lijkt daarmee ook een robuustere oplossing, omdat bij toekomstige versies van het Kadaster bericht, de schema wijzigingen in het bindingmodel opgevangen kunnen worden.

  2. Het team schat in dat XB4J een veel lagere leercurve heeft dan JAXB.

  3. Het vertrouwen in JAXB is gedaald: wie weet welke verrassingen ons nog meer te wachten staan?

De komende sprints gaan we met XB4J aan de slag. Mijn collega ontwikkelaars schrijven de binding modellen en de Java klassen, terwijl ik hun verbetervoorstellen in XB4J verwerk en oplossingen implementeer voor de problemen waar ze tegenaan lopen. De product backlog wordt opnieuw ingeschat en er wordt een ‘minimal viable product’ gedefinieerd op basis van informatie van eindgebruikers. Het schrijven van de binding modellen geeft extra werk vergeleken met JAXB, maar ze zijn met een voorspelbaar tempo te implementeren. Van Kadaster komt het bericht dat uitfasering van versie 4.7 uitgesteld wordt. Eerst wordt gesproken over december, daarna geven ze aan dat ze eind januari 2018 een definitieve einddatum zullen communiceren. Het lijkt erop dat we niet de enige afnemer van het bericht zijn die moeite heeft met de integratie van versie 5.1 in haar systemen. Eind september schatten we in dat we onze software tussen half januari en half februari 2018 helemaal aangepast hebben naar de nieuwe berichtversie. Een schatting die we niet meer aan hoeven passen. Ruim op tijd vóór vrijdag 13 april, de datum die het Kadaster definitief heeft vastgesteld als einddatum voor versie 4.7.

Nawoord

De broncode van XB4J staat op Github. Het project kan via Maven Central als afhankelijkheid in je project worden opgenomen. De ervaringen in het team waren overwegend positief. Ontwikkelaars die niet eerder met XB4J gewerkt hebben, waren snel productief. Het was daarbij wel belangrijk dat ze van een voorbeeld af konden kijken. De foutmelding die XB4J geeft, wanneer het binding model de berichtstructuur niet goed beschrijft is cryptisch. Oplossen daarvan kost tijd. Via logging is wel snel duidelijk wat het probleem is, maar de foutmelding moet gewoon beter. En het schrijven van een binding model blijft monnikenwerk. Naar aanleiding van de toepassing van XB4J in dit project heb ik de volgende prioriteiten opgesteld voor de verdere ontwikkeling:

  1. Voeg gebruikersdocumentatie toe met voorbeelden.

  2. Werk aan tooling om de ontwikkelaar te ontlasten bij het schrijven van een binding model.

  3. Verbeter de foutmeldingen wanneer de bindings niet helemaal overeenkomen met de berichtstructuur.

  4. Implementeer alle functionaliteiten die mogelijk zijn volgens de XML-schema specificaties.

  5. Verbeter de API, bijv. door gebruik te maken van builders of een DSL.

Laat me weten wat jouw ervaringen zijn met XB4J.