JAXB Error : has more than one mapping. Due to two Object Factories with the same Bean

JAXB Error : has more than one mapping. Due to two Object Factories with the same Bean

我有两个 Maven JAXB 项目。

A:Main Maven JAXB 存根 XSD 项目,其中包含 BASKET.xsd

B:Maven JAXB 存根想要将 BASKET.xsd 包装在自己的对象中的用户项目。

这导致两个对象工厂(不同的包),都声明以下内容...

@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);
}

这一代是通过这个插件完成的... org.jvnet.jaxb2.maven2 maven-jaxb2-插件 0.13.2

在应用程序启动时,我收到 CXF-RT-Frotnend-JaxRS 3.1.11 给我一个错误...

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)

在我从 CXF 2.7.7 升级到 3.1.11 之前,这不是我遇到的错误

有谁知道是否有办法让 maven-jaxb2-plugin 不在 UserService ObjectFactory 上生成方法 createBasket(..)??

或者让CXF在两个ObjectFactoty上接受两个相同的方法类?

我的解决方案是改变

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

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

例如在我的申请中-config.xml

  <bean id="jaxbextprovider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
    <property name="singleJaxbContext" value="false"/>
  </bean>

与您的项目一样,我的项目有 2 个包含相同 class 且具有相同元素名称和命名空间的包。据我所知,这混淆了编组过程,因为 JAXB 无法准确判断应该使用哪个映射来解析 XML 和 Java 对象。

如您所见,运行时错误非常相似:

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

虽然我的解决方案略有不同。 classes 是由代码中的 wsimport tool, so I provided a binding file with generateElementProperty="false" to force the tool to ditch JAXBElement generics 生成的,这会影响映射的生成方式。

我的绑定文件最终看起来像这样:

<?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>

...所以我可以在 shell:

中使用此命令调用 wsimport
path-to-your-jdk/bin/wsimport -verbose -extension -keep -Xnocompile -d your-target-dir your-schema.xml -b your-binding-file.xjb

在所有生成的 class 中用 SomeType 替换了 JAXBElement<SomeType>,错误消失了。