unable to marshal type as an element because it is missing an @XmlRootElement annotation for auto generated classes

JavaJakarta EeJaxbSchema

Java Problem Overview


I need to validate Class object against my schema in which I have provided regular expression to validate fields for auto generated JAXB classes. When I try to validate my class object I get below error:

> unable to marshal type "xyz" as an element because it is missing an @XmlRootElement annotation

Here is the code that I use to validate my autogenerated class object:

jc = JAXBContext.newInstance(obj.getClass());
source = new JAXBSource(jc, obj);
Schema schema = schemaInjector.getSchema();
Validator validator = schema.newValidator();
validator.validate(source);

Is there any other way I can solve this?

Java Solutions


Solution 1 - Java

If your class does not have an @XmlRootElement annotation then you can wrap it in an instance of JAXBElement. If you generated your classes from an XML Schema then the generated ObjectFactory may have a convenience method for you.

I have written more about this use case on my blog:

Solution 2 - Java

I solved this problem by using the ObjectFactory class as shown in the example below:

PostTransaction transactionRequest = new PostTransaction();
//Some code here

JAXBElement<PostTransaction> jAXBElement = new ObjectFactory().createPostTransaction(transactionRequest);
 try {
JAXBElement<PostTransactionResponse> aXBElementResponse = (JAXBElement<PostTransactionResponse>) webServiceTemplate.marshalSendAndReceive("wsdlUrl", jAXBElement, new SoapActionCallback("soapMethodName"));

Solution 3 - Java

I suggest you to use Maven plugin maven-jaxb2-plugin to generate classes from a .xsd file. Use a binding file e.g. .xjb to add annotations @XmlRootElement. Example:

Binding file:

<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb"
	xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
	xmlns:annox="http://annox.dev.java.net">

  <globalBindings>
    	<xjc:serializable uid="12343" />
		<xjc:simple/>
  </globalBindings>
  
</bindings>

POM (Maven plugin config):

 <plugin>
    	<groupId>org.jvnet.jaxb2.maven2</groupId>
    	<artifactId>maven-jaxb2-plugin</artifactId>
    	<version>0.8.1</version>
    	<executions>
    		<execution>
    			<phase>generate-sources</phase>
    			<goals>
    				<goal>generate</goal>
    			</goals>
    		</execution>
    	</executions>
    	<configuration>
    		<args>
    			<arg>-Xannotate</arg>
    			<arg>-nv</arg>
    		</args>
    		<extension>true</extension>
    		<forceRegenerate>true</forceRegenerate>
    		<bindingDirectory>${basedir}/src/main/resources/schema/xjb</bindingDirectory>
    		<bindingIncludes>
    			<include>*.xjb</include>
    		</bindingIncludes>
    		<schemas>
    			<schema>
    				<fileset>
    					<directory>${basedir}/src/main/resources/schema/</directory>
    					<includes>
    						<include>*.xsd</include>
    					</includes>
    				</fileset>
    			</schema>
    		</schemas>
    		<debug>true</debug>
    		<verbose>true</verbose>
    		<plugins>
    			<plugin>
    				<groupId>org.jvnet.jaxb2_commons</groupId>
    				<artifactId>jaxb2-basics</artifactId>
    				<version>0.6.2</version>
    			</plugin>
    			<plugin>
    				<groupId>org.jvnet.jaxb2_commons</groupId>
    				<artifactId>jaxb2-basics-annotate</artifactId>
    				<version>0.6.2</version>
    			</plugin>
    			<plugin>
    				<groupId>org.jvnet.jaxb2_commons</groupId>
    				<artifactId>jaxb2-namespace-prefix</artifactId>
    				<version>1.1</version>
    			</plugin>
    		</plugins>
    	</configuration>
    </plugin>
    	

See Maven JAXB2 Plugin User Guide

Solution 4 - Java

I faced same issue due to legacy wsdl that doesn't have xsd schema inside wsdl definition. I solved this issue by having two maven plugins to generate operations from wsdl as well DTD from xsd file as below and for marshalling new ObjectFactory().createHandShake(new HandShake());

  public boolean handShake() {
        JAXBElement<HandShake> request = new ObjectFactory().createHandShake(new HandShake());
        logger.info(String.format("request: {0}", "handshake request"));
        logger.debug("sending request");
        HandShakeResponse handShakeResponse = ((JAXBElement<HandShakeResponse>) getWebServiceTemplate()
                .marshalSendAndReceive(request, new SoapActionCallback(
                        "urn:handShake"))).getValue();
        logger.debug("receive response");
        return handShakeResponse.isReturn();
    }

<plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <version>0.14.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schemaLanguage>WSDL</schemaLanguage>
                    <generatePackage>${contextPathWSDL}</generatePackage>
                    <schemas>
                        <schema>
                            <url>${merchant.WSDL}</url>
                        </schema>
                    </schemas>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.jvnet.jaxb2.maven2</groupId>
                <artifactId>maven-jaxb2-plugin</artifactId>
                <version>0.14.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schemaDirectory>${basedir}/src/main/resources/xsds</schemaDirectory>
                    <schemaIncludes>
                        <include>*.xsd</include>
                    </schemaIncludes>
                    <generatePackage>${contextPathXSD}</generatePackage>
                    <generateDirectory>${basedir}/target/generated-sources/DTD</generateDirectory>
                </configuration>
            </plugin>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser656213View Question on Stackoverflow
Solution 1 - JavabdoughanView Answer on Stackoverflow
Solution 2 - JavaBrighton BerejenaView Answer on Stackoverflow
Solution 3 - JavaXstianView Answer on Stackoverflow
Solution 4 - JavaMohamed.AbdoView Answer on Stackoverflow