javaxmlstreamwriter

XMLStreamWriter exception: Attribute not associated with any element


I'm getting this exception:

javax.xml.stream.XMLStreamException: Attribute not associated with any element
    at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeAttribute(Unknown Source)
    at de.dhbw.horb.routePlanner.parser.GraphDataParser$2.run(GraphDataParser.java:136)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)*

From my code below. I just don't understand where it's comming from.

public void writeEdgeXML() throws XMLStreamException {

    final long[] idCount = new long[1];

    XMLOutputFactory factory = XMLOutputFactory.newInstance();

    try {
        final XMLStreamWriter writer = factory
                .createXMLStreamWriter(new FileOutputStream(
                        GraphDataConstants.CONST_XML_EDGE), "UTF-8");

        writer.writeStartDocument("UTF-8", "1.0");

        while (graphSR.hasNext()) {
            if (graphSR.nextStartElement() && graphSR.isWay()) {

                final Way nextWay = getWay(null);

                Controller.executor.getExecutor().submit(new Runnable() {

                    @Override
                    public void run() {

                        while (nextWay != null && nextWay.hasEdge()) {

                            try {
                                idCount[0]++;
                                Edge e = nextWay.removeFirstEdge();
                                writer.writeStartElement(GraphDataConstants.CONST_EDGE);
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_ID,
                                        String.valueOf(idCount[0]));
                                writer.writeEmptyElement(GraphDataConstants.CONST_EDGE_NODE);
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_ID,
                                        String.valueOf(e.getStartNode()
                                                .getID()));
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_LATITUDE,
                                        String.valueOf(e.getStartNode()
                                                .getLatitude()));
                                writer.writeAttribute(
                                        GraphDataConstants.CONST_EDGE_LONGITUDE,
                                        String.valueOf(e.getStartNode()
                                                .getLongitude()));                                  

                                writer.writeEndElement();
                                writer.flush();

                            } catch  (XMLStreamException e) {
                                   e.printStackTrace();
                            }

                        }
                    }
                });
            }
        }

Solution

  • XMLStreamWriter is not thread safe.

    You're creating a single XMLStreamWriter and then trying to use it to write elements in multiple threads at once. This is not guaranteed to work at all, and if it does the elements and attributes you create won't necessarily end up where you expected them. I suspect the error is down to a race condition along the lines of

    Thread 1             Thread 2
    --------             --------
    1) emptyElement
    2) attribute
                         3) emptyElement
    4) endElement
                         5) attribute (BANG!)
    

    You need to serialize all the XML writing into a single thread.