StAX neboli Streaming API for XML je maximálně jednoduchý a rychlý způsob práce s XML. Pro zápis XML souboru slouží XMLOutputStream, práce s ním je přímočará:
OutputStream out = new FileOutputStream("data.xml");
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = factory.createXMLStreamWriter(out);
writer.writeStartDocument("ISO-8859-1", "1.0");
writer.writeStartElement("greeting");
writer.writeAttribute("id", "g1");
writer.writeCharacters("Hello StAX");
writer.writeEndDocument();
Co ale vůbec není přímočaré jsou jednotlivé implementace. První pokusy jsem dělal s referenční implementací od BEA (jsr173_1.0_ri.jar, jsr173_1.0_api.jar). Všechno fungovalo až do okamžiku, kdy metoda writeCharacters() dostala místo stringu null. Vypadla NullPointerException. V Javadoc dokumentaci k API samozřejmě není požadován ne-nullový parametr, takže je to buď bug, nebo nedokumentované chování.
Abych se tohoto problému zbavil, zkoušel jsem "Weblogic's" implementaci (wls_stax.jar). Ta pro změnu nefungovala vůbec a zahlásila, že nemůže najít referenční (!) implementaci XMLOutputFactory. Proč hledá referenční implementaci? Začal jsem hledat co se vlastně děje při volání XMLOutputFactory.newInstance(). Je to moc zajímavé, nejdřívě se zkusí najít systémové property se jménem skutečné implementace. Když se nenajde, hledá se konfigurační soubor s tímtéž. Nepovede-li se ani to, prohledá se adresář "META-INF/services" v JARu. Není-li jméno implementace ani tam, zkusí se ta referenční. Jinými slovy, wls_stax.jar nemá v META-INF potřebné informace a proto není schopna fungovat standardním způsobem (Ale třeba je to tak správně a wls_stax.jar je určen pro jiné použití. Bohužel se to nedozvím - dokumentace k němu není žádná.). Teprve když jsem ze zvědavosti do META-INF adresář services přidal, fungovat začala. Ovšem se stejnou NullPointerException (Nejspíš sdílí nějaký kód s referenční implementací, protože je také od BEA).
Třetí implementace (sjsxp.jar, jsr173_1.0_api.jar) je součástí Java Web Services Developer Pack od SUNu a netrpí ani jedním problémem. "META-INF/services" má správně a parametr s hodnotou null ho nepoloží. Heuréka.
Existuje ale ještě jeden oříšek. Pokud se první vytvoření factory v multithreadovém prostředí sejde ve stejný okamžik vícekrát, a zároveň běží ve webovém kontejneru (Tomcat 4, 5, Resin 3), jaksi se nepovede. Zahlásí že nelze najít implementaci. Nejspíš to bude souviset s prohledáváním JARu - jeden thread prohledal a chce vytvářet instanci, druhý právě prohledává a někde to uvízne. Důsledky ať si každý odvodí sám...
Hodnocení hvězdičkami používá jako prevenci
opakovaného kliknutí anonymní cookie.
Pokud s tím nesouhlasíte, neklikejte.
Další podrobnosti k cookies zde.