How To Improve Perforamance of Jaxb

Creating the JAXB unmashaller via :


is a very slow operation, if you intending to unmashaller a number of xml documents all with the same schema, you can greatly improve performance by caching the unmashaller instance, see below :

import org.xml.sax.InputSource;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.util.HashMap;
import java.util.Map;
public final class JaxBWrapper<T> {
    private final Unmarshaller unmarshaller;
    private static final Map<ContextDescriptor, Unmarshaller> cache = new HashMap();
     * Creating the JAXB unmashaller via :
     * <p/>
     * javax.xml.bind.JAXBContext.newInstance() is a very slow operation, you can greating improve your performance if you create a cache of these instances, we do this by wrapping the call to newInstance with the following code
    private static class ContextDescriptor {
        private final String jaxbContext;
        private final String schemaLocation;
        public boolean equals(Object o) {
            if (o instanceof ContextDescriptor) {
                final ContextDescriptor un = ((ContextDescriptor) o);
                return jaxbContext.equals(un.jaxbContext) && schemaLocation.equals(un.schemaLocation);
            return false;
        public int hashCode() {
            return (jaxbContext + schemaLocation).hashCode();
        ContextDescriptor(String jaxbContext, String schemaLocation) {
            this.jaxbContext = jaxbContext.trim();
            this.schemaLocation = schemaLocation.trim();
    public JaxBWrapper(final String jaxbContext, final String schemaLocation) {
        unmarshaller = getInstance(jaxbContext, schemaLocation);
    public JaxBWrapper(final String jaxbContex) {
        this(jaxbContex, "your root xsd file path");
    private static Unmarshaller getInstance(final String jaxbContext, final String schemaLocation) {
        final ContextDescriptor contextDescriptor = new ContextDescriptor(jaxbContext, schemaLocation);
        final Unmarshaller unmarshaller = cache.get(contextDescriptor);
        if (unmarshaller != null)
            return unmarshaller;
        final Unmarshaller result = newInstance(jaxbContext, schemaLocation);
        cache.put(contextDescriptor, result);
        return result;
    private static Unmarshaller newInstance(final String jaxbContext, final String schemaLocation) {
        try {
            final JAXBContext context = JAXBContext.newInstance(jaxbContext);
            final Unmarshaller result = context.createUnmarshaller();
            final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            try {
                URI uri = Thread.currentThread().getContextClassLoader().getResource(schemaLocation).toURI()
                final Schema s = schemaFactory.newSchema(toStreamSources(uri));
            } catch (Exception e) {
                throw new RuntimeException(e);
            return result;
        catch (JAXBException e) {
            throw new RuntimeException("Exception occured creating JAXB unmarshaller for context=" + jaxbContext, e);
    public T unmarshallXMLString(final String xmlString) throws Exception {
        final StringReader sr = new StringReader(xmlString.trim());
        final InputSource is = new InputSource(sr);
        return (T) unmarshaller.unmarshal(is);
    static Source[] toStreamSources(@NotNull final URI stream) {
        return new Source[]{new StreamSource(stream.toString())};

If this dose not give you the performance increase that you are looking for, then consider using a SAX parser. If you wish to use a pull parser you could consider using StAX.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License