Jaxb2Marshaller subclasses scanning

957 views Asked by At

I'm using maven-jaxb2-plugin to generate Java classes according to a WSDL. Generated Java classes are under package com.myapp.generated and for example, there is Jaxb2 generated class com.myapp.generated.SomeRequest:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "someRequestType"
})
@XmlRootElement(name = "someRequest")
public class SomeRequest
{
// generated code
}

which I'm extending then I have it in a different package:

package com.myapp.extended.someRequest;
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
 // additional code
}

Then using Spring Boot (v2.2.9) / spring-oxm (v5.2.8) I specify Bean for Jaxb2Marshaller to scan that package:

@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan("com.myapp.extended.*");
    return marshaller;
}

During runtime, unfortunately, there is a problem it doesn't find it:

class package com.myapp.extended.someRequest.SomeRequestExtended; nor any of its super class is known to this context.
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:567) ~[na:1.8.0_201]
...

Does anyone know what is the reason, and how to make it scan specified packages to find the SomeRequestExtended class?

1

There are 1 answers

0
user3157855 On BEST ANSWER

The reason is that the required XmlRootElement on JAXB classes is not inherited in subclasses because interface XmlRootElement doesn't have @Inherited annotation:

package javax.xml.bind.annotation;

@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
public @interface XmlRootElement {
    java.lang.String namespace() default "##default";

    java.lang.String name() default "##default";
}

To solve the issue, you can manually add/copy it from parent class to subclass:

package com.myapp.extended.someRequest;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "someRequestType"
})
@XmlRootElement(name = "someRequest")
class SomeRequestExtended extends com.myapp.generated.SomeRequest {
 // additional code
}

Also make sure, that the @XmlAccessorType(XmlAccessType.FIELD) and @XmlType are still valid in subclass - in my example, the field should be visible, or you can change the definition to getter method using XmlAccessType.PUBLIC_MEMBER

HINT: Additionally, if there is, and usually is, a file package-info.java generated by JAXB, then it should also be copied to a new package, like in my example to: package com.myapp.extended.someRequest; If not there might be problems when resolving classes by marshaller!