3

I have two Maven JAXB Projects.

A: Main Maven JAXB stubs XSD project, this contains BASKET.xsd

B: Maven JAXB stubs User-Project that wants to wrap BASKET.xsd in their own Objects.

This results in TWO Objects factories (different packages), both declare the following...

@XmlElementDecl(namespace = "http://www.bob.org/bob/namespace/", name = "Basket")
public JAXBElement<BasketType> createBasket(BasketType value) {
    return new JAXBElement<BasketType>(QNAME, BasketType.class, null, value);
}

This generation is done via this plugin... org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.13.2

On application start I get CXF-RT-Frotnend-JaxRS 3.1.11 giving me an error...

017-07-03 14:38:54,613845801: WARN  : [RMI TCP Connection(3)-127.0.0.1] [] org.apache.cxf.jaxrs.utils.ResourceUtils: No JAXB context can be created
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
The element name {http://www.bob.org/bob/namespace/}Basket has more than one mapping.
    this problem is related to the following location:
        at public javax.xml.bind.JAXBElement com.bob.bean.ObjectFactory.createBasket(org.bob.BasketType)
        at com.bob.bean.ObjectFactory
    this problem is related to the following location:
        at public javax.xml.bind.JAXBElement org.userservice.bean.ObjectFactory.createBasket(org.bob.BasketType)

This wasn't an error I got untill I upgraded from CXF 2.7.7 to 3.1.11

Does anyone know if there is a way to get maven-jaxb2-plugin to not generate the method createBasket(..) on the UserService ObjectFactory??

Or to get CXF to accept the two methods, which are identical, on the two ObjectFactoty classes?

jeff porter
  • 6,560
  • 13
  • 65
  • 123

2 Answers2

1

My soloution was to change

<property name="singleJaxbContext" value="true"/>

to

<property name="singleJaxbContext" value="false"/>

e.g. in my application-config.xml

  <bean id="jaxbextprovider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
    <property name="singleJaxbContext" value="false"/>
  </bean>
jeff porter
  • 6,560
  • 13
  • 65
  • 123
  • 1
    Can you provide an explanation for your solution? Thank you. – Marco Nov 07 '19 at 13:34
  • 1
    @Marco If your project is using one single JAXB context for all your schemas, you might come across the issue OP reported when you have multiple JAXB elements with the same name. See more here: https://stackoverflow.com/a/13949844/2516673 – Fappaz Feb 10 '22 at 20:44
1

Like your project, mine had 2 packages containing the same class with same element name and namespace. From what I got, that confuses the marshalling process, as JAXB can't tell exactly which mapping it should use to parse between XML and Java object.

As you can see, the runtime error is quite similar:

The element name {http://schemas.foobar.com/2021/12/01/ws/platform/coretypes}Identifiers has more than one mapping.
        this problem is related to the following location:
                at public javax.xml.bind.JAXBElement myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.ObjectFactory.createIdentifiers(myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.Identifiers)
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.ObjectFactory
                at protected javax.xml.bind.JAXBElement myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.Coding.nameOther
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.Coding
                at protected myapp.visit.com.foobar.schemas._2021._12._01.ws.platform.coretypes.Coding myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ClinicianRole.clinicianRoleType
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ClinicianRole
                at protected java.util.List myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ArrayOfClinicianRole.clinicianRole
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ArrayOfClinicianRole
                at public myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ArrayOfClinicianRole myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ObjectFactory.createArrayOfClinicianRole()
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.clinician.ObjectFactory
        this problem is related to the following location:
                at public javax.xml.bind.JAXBElement myapp.appointment.com.foobar.schemas._2021._12._01.ws.platform.coretypes.ObjectFactory.createIdentifiers(myapp.appointment.com.foobar.schemas._2021._12._01.ws.platform.coretypes.Identifiers)
                at myapp.appointment.com.foobar.schemas._2021._12._01.ws.platform.coretypes.ObjectFactory
                at protected javax.xml.bind.JAXBElement myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.appointment.AppointmentLink.appointmentIdentifier
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.appointment.AppointmentLink
                at public javax.xml.bind.JAXBElement myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.appointment.ObjectFactory.createAppointmentLink(myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.appointment.AppointmentLink)
                at myapp.visit.com.foobar.schemas._2021._12._01.ws.pas.appointment.ObjectFactory

My solution though was slightly different. The classes were being generated by the wsimport tool, so I provided a binding file with generateElementProperty="false" to force the tool to ditch JAXBElement generics in the code, which impacts how the mappings are generated.

My binding file ended up looking like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings jaxb:version="2.0"
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings generateElementProperty="false"/>
</jaxb:bindings>

...so I could call wsimport with this command in my shell:

path-to-your-jdk/bin/wsimport -verbose -extension -keep -Xnocompile -d your-target-dir your-schema.xml -b your-binding-file.xjb

That replaced JAXBElement<SomeType> with SomeType in all generated classes, and the error was gone.

Fappaz
  • 3,033
  • 3
  • 28
  • 39