I am trying to create XML using the JaxB Marshalling
approach. I want to skip the parent tag for certain children or may add a new XML
parent tag for a certain element. Hence I am trying to use the @XmlPath
from import org.eclipse.persistence.oxm.annotations.XmlPath;
.
I am following the blog from the founder (Blog on @XmlPath) to make it work but for some reason, the @XmlPath
has no impact and the output XML does not match as shown in the blog. I followed all the process mentioned within the blog and also mentioned on various answers here.
All my classes are within the model.jaxb
package. Also, I have created a jaxb.properties
file within that package.
Following is my Customer
class:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@Getter
@Setter
@NoArgsConstructor
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlPath("contact-info/billing-address")
private Address billingAddress;
@XmlPath("contact-info/shipping-address")
private Address shippingAddress;
}
Following is my Address
class:
@Getter
@Setter
@NoArgsConstructor
public class Address {
private String street;
}
Following is Demo
class:
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Customer customer = new Customer();
Address billingAddress = new Address();
billingAddress.setStreet("1 Billing Street");
customer.setBillingAddress(billingAddress);
Address shippingAddress = new Address();
shippingAddress.setStreet("2 Shipping Road");
customer.setShippingAddress(shippingAddress);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(customer, System.out);
}
}
The XML I getting with and without @XmlPath
are the same actually. So seems like the @XmlPath
has no impact during the marshalling.
<customer>
<billingAddress>
<street>1 Billing Street</street>
</billingAddress>
<shippingAddress>
<street>2 Shipping Road</street>
</shippingAddress>
</customer>
I have created jaxb.properties
file within my package model.jaxb
with the content:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
As per the blog the output XML should be something like this:
<customer>
<contact-info>
<billing-address>
<street>1 Billing Street</street>
</billing-address>
<shipping-address>
<street>2 Shipping Road</street>
</shipping-address>
</contact-info>
<customer>
I am not sure what am I doing wrong due to which I am unable to get the XML as I expect. I tried a lot of things but none worked so posting the same here.
Can someone please help me with how can I make the @XmlPath
kicking during the marshalling so that I can get the expected tag during the marshalling?
**** EDITED *****
I am using Java version 15.0.01 as per the Intellij IDE File -> Project Structure
. I saw one answer where it mentioned Moxy
does not work directly above Java 11
Answer Java 11.0 above.
So I did following things:
- I added the dependency and
build
as mentioned in the above answer so mypom.xml
looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>model.jaxb</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>model-jaxb</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
</project>
When I run the program then I get the error:
Exception in thread "main" java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException
Caused by: java.lang.ClassNotFoundException: jakarta.xml.bind.JAXBException
I tried a lot of things mentioned on StackOverflow for this error and most of the answers mentioned adding the
dependency` I have added all the dependency mentioned in the answer. I am not sure what's going wrong.
Can someone please assist me with how can I fix this issue?
See Question&Answers more detail:os