adam bien's blog

From POJO to XML and Back with JAXB and Java 11+ 📎

Java Architecture for XML Binding (JAXB) API was deprecated in Java 9 and with the JEP 320: Remove the Java EE and CORBA Modules removed from Java SE 11.

At the same time the JAXB module was rebranded to Jakarta XML Binding: eclipse-ee4j.github.io/jaxb-ri/ and maintained as Java EE / Jakarta EE API and implementation.

Starting with Java 11+, you will have to add the JAXB API, as well as, the JAXB implementation as additional dependencies:


<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.airhacks</groupId>
    <artifactId>jaxb</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.6.2</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.3</version>
            <scope>runtime</scope>
        </dependency>
        
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
</project>    

Now a Java POJO:


import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Duke {

    private String language;
    private int age;

    public Duke() {}

    public Duke(String language, int age) {
        this.language = language;
        this.age = age;
    }
}    

...can be serialized and deserialized:


import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class DukeTest {

    private JAXBContext context;

    @BeforeEach
    public void init() throws JAXBException {
        this.context = JAXBContext.newInstance(Duke.class);

    }

    @Test
    public void serialization() throws JAXBException {
        Marshaller marshaller = this.context.createMarshaller();
        marshaller.marshal(new Duke("java", 2), new File("duke.xml"));

        Unmarshaller unmarshaller = this.context.createUnmarshaller();
        Object unmarshalled = unmarshaller.unmarshal(new File("duke.xml"));
    }
}

...into XML:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<duke>
    <language>java</language>
    <age>2</age>
</duke>    

See the serialization in action in a 5 minutes screencast: With POJOs To XML And Back With JAXB