I have 2 xsd schemas from which Im generating a class Message using maven-jaxb2-plugin. The main xsd is message.xsd and it imports common.xsd which holds some common types. However both have different target namespaces.
This results in jaxb xml unmarshaller not reading the fields in the xml and using the default values. If in the generated class I manually set the namespace to "message" it works. Is there a way to place both generated class fields under the same namespace? Or perhaps is my XML message wrong? Or am I missing a jaxb2 generator parameter somewhere? Should I use a jaxb binding to solve this?
I cannot change the xsd namespace definitions. A lot of answers are so very close to what I need but none are the actual issue I have.
This generates a Message class that looks sort of like this:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"computer"
})
@XmlRootElement(name = "message", namespace = "message")
public class Message implements ToString2
{
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"date",
"info"
})
public static class Computer implements ToString2
{
@XmlElement(namespace = "message", required = true)
protected int date;
@XmlElement(name = "info", namespace = "message", required = true)
protected InfoType info;
}
}
The Info class is generated from the common.xsd and it looks like this:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "InfoType", propOrder = {
"number",
"id"
})
public class InfoType implements ToString2
{
@XmlElement(namespace = "")
@XmlSchemaType(name = "integer")
protected int number;
@XmlElement(namespace = "")
@XmlSchemaType(name = "integer")
protected int id;
}
I send this xml:
<?xml version="1.0" encoding="utf-8"?>
<message xmlns="message">
<computer>
<info>
<name>2</name>
<id>999998</id>
</info>
<date>20220508</date>
</computer>
</message>
package-info.java has the namespace set to "common" which is why I assume the namespace on the fields in Info are "" it looks like this:
@javax.xml.bind.annotation.XmlSchema(namespace = "common", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.myapp.message
pom:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
<configuration>
<accessExternalSchema>all</accessExternalSchema>
<specVersion>2.1</specVersion>
<cleanPackageDirectories>false</cleanPackageDirectories>
<extension>true</extension>
<args>
<arg>-Xfluent-api</arg>
<arg>-XtoString</arg>
</args>
<plugins>
<plugin>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>${maven-jaxb2-plugin.fluent-api.version}</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>${jaxb2-basics-runtime.version}</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<id>generate-message</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/message</schemaDirectory>
<schemaIncludes>
<include>message.xsd</include>
</schemaIncludes>
<bindingDirectory>src/main/resources/jaxb</bindingDirectory>
<generateDirectory>target/generated-sources/jaxb/message</generateDirectory>
<generatePackage>com.myapp.message
</generatePackage>
</configuration>
</execution>
</executions>
</plugin>
From other xsd generations I assume changing targetNamespace to the same namespace and using include instead of import would do the trick, however that is not an option.
Manually changing namespace in the @XmlElement(namespace = "") solves the problem, however that doesn't do much for me as it will get written over on the next generation.
I tried looking into xjb. However Im unsure if that is actually the way, if I set it to bind to the top element it has trouble resolving types from the commons.xsd - might be worth pursing?
We don't have the common.xsd
generation but I think you shouldn't generate the common and message into the same package (tag generatePackage
).
By doing so, Jaxb doesn't know which package annotation is the right one.
You can also upgrade to at least v2 version of maven-jaxb2-plugin following the upgrade guide