Java 不使用JAXB将@XmlRootElement封送到字符串

Java 不使用JAXB将@XmlRootElement封送到字符串,java,maven,jaxb,wsdl2java,jaxb2-maven-plugin,Java,Maven,Jaxb,Wsdl2java,Jaxb2 Maven Plugin,我需要将一个JAXB生成的对象封送到String。问题是它没有@XmlRootElement注释。它不是根元素。XSD中的元素如下所示: <xs:complexType name="CompletedAssessmentInstance"> <xs:complexContent mixed="false"> <xs:extension base="tns:AssessmentInstance"> <xs:seque

我需要将一个
JAXB
生成的对象封送到
String
。问题是它没有
@XmlRootElement
注释。它不是根元素。
XSD
中的元素如下所示:

  <xs:complexType name="CompletedAssessmentInstance">
    <xs:complexContent mixed="false">
      <xs:extension base="tns:AssessmentInstance">
        <xs:sequence>
          <xs:element minOccurs="0" name="CompletionDate" type="xs:dateTime"/>
          <xs:element minOccurs="0" name="CustomResultsXML" nillable="true" type="xs:string"/>
          <xs:element minOccurs="0" name="NormedScores" nillable="true" type="tns:NormedScores"/>
          <xs:element minOccurs="0" name="RawScore" type="xs:decimal"/>
          <xs:element minOccurs="0" name="TimeTaken" type="xs:int"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="CompletedAssessmentInstance" nillable="true" type="tns:CompletedAssessmentInstance"/>
private static JAXBContext jc = createJaxbContext();

private static JAXBContext createJaxbContext() {
    try {
        ClassLoader cl = com.cubiksonline._2009._08.assessmentprovider.ObjectFactory.class.getClassLoader();
        return JAXBContext.newInstance("com.cubiksonline._2009._08.assessmentprovider", cl);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}
private static JAXBContext createJaxbContext() {
    try {
        return JAXBContext.newInstance(CompletedAssessmentInstance.class);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}
我正在初始化我的
JAXB
上下文,如下所示:

  <xs:complexType name="CompletedAssessmentInstance">
    <xs:complexContent mixed="false">
      <xs:extension base="tns:AssessmentInstance">
        <xs:sequence>
          <xs:element minOccurs="0" name="CompletionDate" type="xs:dateTime"/>
          <xs:element minOccurs="0" name="CustomResultsXML" nillable="true" type="xs:string"/>
          <xs:element minOccurs="0" name="NormedScores" nillable="true" type="tns:NormedScores"/>
          <xs:element minOccurs="0" name="RawScore" type="xs:decimal"/>
          <xs:element minOccurs="0" name="TimeTaken" type="xs:int"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="CompletedAssessmentInstance" nillable="true" type="tns:CompletedAssessmentInstance"/>
private static JAXBContext jc = createJaxbContext();

private static JAXBContext createJaxbContext() {
    try {
        ClassLoader cl = com.cubiksonline._2009._08.assessmentprovider.ObjectFactory.class.getClassLoader();
        return JAXBContext.newInstance("com.cubiksonline._2009._08.assessmentprovider", cl);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}
private static JAXBContext createJaxbContext() {
    try {
        return JAXBContext.newInstance(CompletedAssessmentInstance.class);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}
此包:
com.cubiksonline.\u 2009.\u 08.assessmentprovider
是一个包,其中包含所有
JAXB
生成的类,包括和
CompletedAssessmentInstance
。问题是当
marshaller.marshal(rootElement,writer)时被调用时,我得到以下异常:

Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context]
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
    at com.groupgti.esb.assessments.cubiks.CubiksFactory.completedAssessmentInstanceToString(CubiksFactory.java:272)[647:com.groupgti.esb.online.tests.cubiks:1.2.0.SNAPSHOT]
    ... 40 more
Caused by: javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:144)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:189)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:316)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:323)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72)
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
    ... 43 more
Caused by: javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:625)
    at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:141)
    ... 49 more

有人知道问题出在哪里吗?

我找到了解决这个问题的方法。我必须为特定类创建
JAXBContext
,如下所示:

  <xs:complexType name="CompletedAssessmentInstance">
    <xs:complexContent mixed="false">
      <xs:extension base="tns:AssessmentInstance">
        <xs:sequence>
          <xs:element minOccurs="0" name="CompletionDate" type="xs:dateTime"/>
          <xs:element minOccurs="0" name="CustomResultsXML" nillable="true" type="xs:string"/>
          <xs:element minOccurs="0" name="NormedScores" nillable="true" type="tns:NormedScores"/>
          <xs:element minOccurs="0" name="RawScore" type="xs:decimal"/>
          <xs:element minOccurs="0" name="TimeTaken" type="xs:int"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="CompletedAssessmentInstance" nillable="true" type="tns:CompletedAssessmentInstance"/>
private static JAXBContext jc = createJaxbContext();

private static JAXBContext createJaxbContext() {
    try {
        ClassLoader cl = com.cubiksonline._2009._08.assessmentprovider.ObjectFactory.class.getClassLoader();
        return JAXBContext.newInstance("com.cubiksonline._2009._08.assessmentprovider", cl);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}
private static JAXBContext createJaxbContext() {
    try {
        return JAXBContext.newInstance(CompletedAssessmentInstance.class);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}

这并不能解决问题,只是权宜之计。我使用
cxf-codegen-plugin:2.6.0
WSDL
文件生成类,我注意到如果我将版本更改为
cxf-codegen-plugin:2.4.2
使用类加载器一切正常。如果我能找到问题,我会在这里发布解决方案。

因为您使用的是JAXB RI,所以实现
JAXBContext
toString()
将输出所有映射的类。您可以检查一下以确保包含
com.cubiksonline.\u 2009.\u 08.assessmentprovider.CompletedAssessmentInstance
。另外,由于JAXB是一个规范(JSR-222),您可以尝试另一个实现,例如EclipseLink MOXy(我是MOXy的负责人),看看这是否只是JAXB RI中的一个bug。这很奇怪,因为当我在JAXBContext上执行字符串时,它只列出了9个类,在这个包中大约有50个类,这个类com.cubiksonline.\u 2009.\u 08.assessmentprovider.CompletedAssessmentInstance不包括在内。我已经找到了解决办法。我必须像这样初始化JAXB上下文:JAXBContext.newInstance(CompletedAssessmentInstance.class),但我仍然无法理解为什么JAXB没有从指定包加载所有类。您可能在JAXB RI中发现了一个bug。您可以尝试JAXB(JSR-222)的更新版本或替代实现来确认。我使用的是cxf codegen插件:2.6.0,如果我将版本更改为cxf codegen插件:2.4.2一切正常,我会看到所有类都来自JAXBContext。但我查看了依赖关系树,发现它们都使用组ID:com.sun.xml.bind工件ID:jaxb impl Version:2.1.13。这是相同的版本。好的,这似乎是cxf codegen插件中的一个bug,而不是JAXB参考实现。我建议向CXF提交一个bug。