StAX API and Maven: What stax-api Is and When You Need It

StAX (Streaming API for XML, JSR 173) is Java’s standard pull parser for reading and writing XML, found in the package javax.xml.stream. It has been part of the JDK since Java 6 (the Javadoc for XMLStreamReader says “Since: 1.6”), so on Java 6 or later you normally do not need the Maven artifact javax.xml.stream:stax-api at all. That jar, last released as version 1.0-2 in October 2008, only matters for Java 5 projects, and today it usually turns up as an unwanted transitive dependency that you exclude.

Advertisement

What is the StAX API?

StAX is a Java API for processing XML as a stream. The JSR 173 specification, led by BEA with support from Sun Microsystems, passed its final Java Community Process ballot in March 2004. It sits between the two older XML APIs in Java:

  • DOM loads the whole document into a tree in memory. Easy to move around in, but a 500 MB file needs a lot more than 500 MB of heap.
  • SAX streams the document and pushes events to your callback methods. Memory use is small, but your code has to track where it is in the document through handler state.
  • StAX also streams, but your code pulls the next item when it is ready, in an ordinary loop. You get SAX-level memory use with code that reads top to bottom.

StAX can also write XML (XMLStreamWriter and XMLEventWriter), which SAX cannot.

Cursor API vs event (iterator) API

StAX offers two styles of reading, both created from an XMLInputFactory.

PointCursor APIEvent (iterator) API
Main reader interfaceXMLStreamReaderXMLEventReader
Writer interfaceXMLStreamWriterXMLEventWriter
What next() givesAn int event type; you then query the reader (getLocalName(), getText())An XMLEvent object you can keep, pass around or peek at
Memory and speedLowest overhead, no object per eventSlightly more, one object per event
Best forFast parsing of large files, performance-critical codePipelines and filters that pass events to other code

The same loop in event style looks like this (it also needs imports for javax.xml.stream.XMLEventReader and javax.xml.stream.events.XMLEvent):

XMLEventReader events = factory.createXMLEventReader(new StringReader(xml));
while (events.hasNext()) {
    XMLEvent e = events.nextEvent();
    if (e.isStartElement()) {
        System.out.println(e.asStartElement().getName().getLocalPart());
    }
}

StAX vs SAX vs DOM

FeatureDOMSAXStAX
ModelTree in memoryPush (callbacks)Pull (your loop)
Memory useGrows with document sizeSmall, constantSmall, constant
Random access / go backYesNoNo, forward only
Modify the documentYesNoNo (but can write a new stream)
Write XMLYes, via a TransformerNoYes
Stop earlyOnly after full loadAwkward (throw an exception)Easy, just leave the loop
Packageorg.w3c.dom, javax.xml.parsersorg.xml.sax, javax.xml.parsersjavax.xml.stream
In the JDK sinceJava 1.4 (JAXP)Java 1.4 (JAXP)Java 6

Rule of thumb: DOM for small configuration files you edit, StAX for large or streamed XML such as data feeds, SOAP messages and exports, and SAX mainly in older code that already uses it.

Advertisement

Do you need the stax-api Maven dependency?

If your project runs on Java 6 or later, no. The javax.xml.stream classes ship with the JDK (in the java.xml module from Java 9), along with a working parser implementation. Adding the stax-api jar gives you a second copy of the same interfaces and nothing else.

You will meet the artifact under two sets of coordinates on Maven Central:

CoordinatesLatest versionReleasedNotes
javax.xml.stream:stax-api1.0-2October 2008Sun’s API jar, CDDL / GPL licence; no dependencies
stax:stax-api1.0.1August 2006The older Codehaus build, Apache 2.0 licence

The only case where you would declare it yourself is a legacy project that still has to run on Java 5, which had no StAX in the JDK:

<dependency>
    <groupId>javax.xml.stream</groupId>
    <artifactId>stax-api</artifactId>
    <version>1.0-2</version>
</dependency>

On Java 5 you would also need an implementation jar, such as Woodstox, because the API jar holds only interfaces and the factory lookup code.

Why stax-api causes problems

Old libraries written for Java 5 declared stax-api as a dependency, so Maven still pulls it in transitively today. On a modern JDK the duplicate javax.xml.stream classes can lead to class loading conflicts, typically a LinkageError or “loader constraint violation” inside application servers, or split-package errors when the jar ends up on the Java module path. Even when nothing breaks, it is dead weight in your build.

How to find and exclude stax-api in Maven

First find which dependency brings it in:

Advertisement
mvn dependency:tree -Dincludes=javax.xml.stream:stax-api,stax:stax-api

Then add an exclusion under that dependency in pom.xml. Excluding both coordinates covers either variant (the library name here is a placeholder):

<dependency>
    <groupId>com.example</groupId>
    <artifactId>legacy-xml-lib</artifactId>
    <version>2.1.0</version>
    <exclusions>
        <exclusion>
            <groupId>javax.xml.stream</groupId>
            <artifactId>stax-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>stax</groupId>
            <artifactId>stax-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Run the build and your tests afterwards. The JDK’s own StAX classes take over, and code that imports javax.xml.stream compiles unchanged. In Gradle the same idea is exclude group: ‘javax.xml.stream’, module: ‘stax-api’.

StAX implementations

The API is a set of interfaces; a parser implementation does the work. XMLInputFactory.newInstance() finds one through a lookup order: the javax.xml.stream.XMLInputFactory system property, then configuration files, then the service loader (a jar on the classpath that registers itself), and finally the JDK’s built-in default.

  • JDK built-in parser: derived from Sun’s Java Streaming XML Parser (SJSXP), which Oracle describes as a non-validating, namespace-aware pull parser built on the Xerces2 codebase. It is used when nothing else is configured.
  • Woodstox: a widely used open-source implementation of StAX and its extended Stax2 API, often chosen for speed and extra features. Maven coordinates com.fasterxml.woodstox:woodstox-core; the latest release listed on Maven Central is 7.2.2 (August 2026). Adding it is enough for newInstance() to pick it up:
<dependency>
    <groupId>com.fasterxml.woodstox</groupId>
    <artifactId>woodstox-core</artifactId>
    <version>7.2.2</version>
</dependency>
  • Aalto XML: another FasterXML parser implementing StAX, built for high throughput and non-blocking parsing.

StAX example: reading XML with XMLStreamReader

This program reads a small XML string with the cursor API and prints each book’s id, title and price. It needs no Maven dependency on Java 6 or later.

import java.io.StringReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class StaxDemo {
    public static void main(String[] args) throws XMLStreamException {
        String xml = "<library>"
                   + "<book id='1'><title>Machine Design</title><price>450</price></book>"
                   + "<book id='2'><title>Strength of Materials</title><price>380</price></book>"
                   + "</library>";

        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(xml));

        while (reader.hasNext()) {
            int event = reader.next();
            if (event == XMLStreamConstants.START_ELEMENT) {
                String name = reader.getLocalName();
                if (name.equals("book")) {
                    System.out.println("book id=" + reader.getAttributeValue(null, "id"));
                } else if (name.equals("title") || name.equals("price")) {
                    System.out.println("  " + name + ": " + reader.getElementText());
                }
            }
        }
        reader.close();
    }
}

Expected output:

book id=1
  title: Machine Design
  price: 450
book id=2
  title: Strength of Materials
  price: 380

How it works, step by step:

Advertisement
  1. The reader starts in the START_DOCUMENT state. Each call to next() moves the cursor to the next event and returns its type as an int constant from XMLStreamConstants.
  2. On a START_ELEMENT for book, getAttributeValue(null, “id”) reads the id attribute; passing null means “ignore the namespace”.
  3. On title or price, getElementText() reads all the text up to the matching end tag and leaves the cursor on that END_ELEMENT. It is safer than getText() on CHARACTERS events, because a parser may split long text into several CHARACTERS events.
  4. The library element starts too, but the code ignores it. After the final end tag the reader reaches END_DOCUMENT, hasNext() returns false and the loop ends.

The XML string has no whitespace between tags, so there are no whitespace-only text events to skip. With a pretty-printed file you would see CHARACTERS events for the line breaks; check reader.isWhiteSpace() or, as here, read text only where you expect it. Markup basics are shared with HTML; see our page on HTML for how tags and attributes work.

Common mistakes with StAX

  • Adding stax-api to a Java 8, 11, 17 or 21 project because an old tutorial said so. Remove it.
  • Calling getLocalName() on a CHARACTERS event. It throws IllegalStateException; check the event type first.
  • Assuming text comes as one event. Use getElementText() or set the factory property XMLInputFactory.IS_COALESCING to true.
  • Not closing the reader. XMLStreamReader.close() frees parser resources but does not close the underlying stream or reader, so close that too (try-with-resources on the stream).
  • Parsing untrusted XML with default settings. Turn off DTDs and external entities (XMLInputFactory.SUPPORT_DTD set to false) to block XXE attacks.

FAQs

What is stax-api?

stax-api is the Maven artifact (javax.xml.stream:stax-api, latest 1.0-2 from 2008, or the older stax:stax-api 1.0.1) that holds the interfaces of the Streaming API for XML, JSR 173. Since Java 6 the same interfaces are part of the JDK, so the jar is only needed on Java 5.

Is StAX included in the JDK?

Yes. javax.xml.stream has been in Java SE since Java 6, with a built-in parser, and from Java 9 it lives in the java.xml module. You can use XMLInputFactory and XMLStreamReader without adding any dependency.

What is the difference between StAX and SAX?

Both stream XML with low memory use. SAX pushes events to callback methods you register; StAX lets your code pull the next event in a loop, which is easier to read and to stop early. StAX can also write XML; SAX cannot.

How do I exclude stax-api in Maven?

Run mvn dependency:tree to find the dependency that brings it in, then add an exclusions block to that dependency with groupId javax.xml.stream and artifactId stax-api (and stax / stax-api for the older variant).

What is Woodstox?

Woodstox is an open-source, high-performance StAX implementation (Maven: com.fasterxml.woodstox:woodstox-core). With it on the classpath, XMLInputFactory.newInstance() uses Woodstox instead of the JDK’s built-in parser.

Advertisement