【问题标题】:JAXB generating unwanted @XMLValueJAXB 生成不需要的 @XMLValue
【发布时间】:2015-10-04 20:59:59
【问题描述】:

一个问题已经解决了大约半周,需要帮助,因为我似乎无法取得任何进展。

我继承了一个应用程序,它已经 8 年没有得到很好的处理......仍然在 Java 1.4 上,Maven1 构建,8 年没有新的单元测试......

目前升级到 Java 1.6(Java 1.8 分支也同时进行,将对两者进行测试)和 Maven 3.3.3 进展顺利 - 取得了巨大的进展。

现在我碰壁了,有一段时间没有突破。

旧资源使用本地 JAXB 1.3 jar 从大型 XSD 生成类。

我不得不从 JAXB1.3 迁移到 JAXB2.1——这也意味着随着命名约定的改变,我不得不花费大量时间重写对生成的类的所有引用。 无论如何,花了很多时间来编译代码。

最后,它编译了,我尝试了一个单元测试来看看它是如何工作的。 这就是我遇到问题的地方。

大多数编译的类都可以正常工作,但是当我尝试生成 JAXBContext 时,其中三个包会抛出异常:

在派生另一个类的类上不允许使用@XmlValue。

我已将问题缩小到出现在几个生成的类中的模式。 导致异常的类在模式中定义如下:

    <xs:element name="ContactName">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="First" type="xs:string"/>
                <xs:attribute name="Middle" type="xs:string"/>
                <xs:attribute name="Last" type="xs:string"/>
                <xs:attribute name="Name" type="xs:string"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

然后这个元素在另一个中被引用如下:

<xs:element name="ContactInfo">
    <xs:complexType>
        <xs:annotation>
            <xs:documentation>Common contact information</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element ref="ContactName" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element ref="ContactID" minOccurs="0"/>
            <xs:element ref="ContactDivision" minOccurs="0" maxOccurs="unbounded"/>
            .....

这生成为:

联系人姓名:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "value"
})
@XmlRootElement(name = "ContactName")
public class ContactName
    extends BaseJaxbDoc
    implements Serializable, Cloneable, CopyTo
{

    private final static long serialVersionUID = 47110815L;
    @XmlValue
    protected String value;
    @XmlAttribute(name = "First")
    protected String first;
    @XmlAttribute(name = "Middle")
    protected String middle;
    @XmlAttribute(name = "Last")
    protected String last;
    @XmlAttribute(name = "Name")
    protected String name;

然后在ContactInfo中声明如下:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "contactName",
    "contactID",
    "contactDivision",
    "contactPhone",
    "contactPhoneHome",
    "contactPhoneMobile",
    "contactFax",
    "contactEmail",
    "contactEmail2"
})
@XmlRootElement(name = "ContactInfo")
public class ContactInfo
    extends BaseJaxbDoc
    implements Serializable, Cloneable, CopyTo
{

    private final static long serialVersionUID = 47110815L;
    @XmlElement(name = "ContactName")
    protected List<ContactName> contactName;

抛出的异常在:

this problem is related to the following location:
    at protected java.lang.String xxx.xx.xxxx.xxxx.orders.jaxb.ContactName.value
    at xxx.xx.xxxx.xxxx.orders.jaxb.ContactName
    at protected java.util.List xxx.xx.xxxx.xxxx.orders.jaxb.ContactInfo.contactName
    at xxx.xx.xxxx.xxxx.orders.jaxb.ContactInfo
    at protected java.util.List xxx.xx.xxxx.xxxx.orders.jaxb.CustomerReference.contactInfo
    at xxx.xx.xxxx.xxxx.orders.jaxb.CustomerReference
    at protected java.util.List xxx.xx.xxxx.xxxx.orders.jaxb.Item.customerReference
    at xxx.xx.xxxx.xxxx.orders.jaxb.Item
    at public xxx.xx.xxxx.xxxx.orders.jaxb.Item xxx.xx.xxxx.xxxx.orders.jaxb.ObjectFactory.createItem()
    at xxx.xx.xxxx.xxxx.orders.jaxb.ObjectFactory

在原始模式上有一个 XML 转换,剥离 cmets 并创建 jaxb:typesafeEnum 类型。然后转换后的模式与 jxb 绑定文件一起使用,将所有内容绑定到内部 jaxb 帮助程序超类 - BaseJaxbDoc

        <jaxb:globalBindings generateIsSetMethod="true">
        <xjc:serializable uid="47110815"/>
        <xjc:superClass name="xxx.xx.xxxx.xxxx.helpers.BaseJaxbDoc"/>
        <jaxb:javaType name="java.math.BigDecimal" xmlType="xs:decimal" 
             parseMethod="xxx.xx.xxxx.xxxx.helpers.AmountConverter.parseAmount" 
            printMethod="xxx.xx.xxxx.xxxx.helpers.AmountConverter.printAmount"/>
        </jaxb:globalBindings>

这是因为我在 9 个不同的模式上使用 xjc,它们都生成 JAXB 类包。

所有类都具有相同的超类(在每个模式的绑定文件中定义),只实现一次 JAXB 编组/解组类以及其他一些辅助函数。 所以我的问题是当我无法修改架构时如何解决这个异常? XSLT 中的内容或绑定文件中的内容?

我的 Maven 依赖项: 对于 JAXB: org.jvnet.jaxb2.maven2 maven-jaxb21-插件 0.13.0

JAXB 运行时: org.glassfish.jaxb jaxb 运行时 2.2.11

【问题讨论】:

  • 您如何以及为什么生成扩展 BaseJaxbDoc?如果你删除它,它会工作吗?
  • 感谢您的回复,我也会更新问题以添加此信息。在原始模式上有一个 XML 转换,剥离 cmets 并创建 jaxb:typesafeEnum 类型。然后转换后的模式与 jxb 绑定文件一起使用,将所有内容绑定到内部 jaxb 帮助程序超类 - BaseJaxbDoc 这是因为我在 9 个不同的模式上使用 xjc,所有这些都生成 JAXB 类包。这些类都具有相同的超类(在每个模式的绑定文件中定义),只实现一次 JAXB 编组/解组类,以及其他一些辅助函数。

标签: jaxb jaxb2 maven-jaxb2-plugin


【解决方案1】:

尝试使用@XmlTransient 注释BaseJaxbDoc

您遇到的问题是here:

                if(getBaseClass()!=null) {
                    builder.reportError(new IllegalAnnotationException(
                        Messages.XMLVALUE_IN_DERIVED_TYPE.format(), p ));
                }

JAXB 认为您的 BaseJaxbDoc 是一个基类。因此,您应该删除 xjc:superClass 或让 JAXB 认为您的类没有基类。

当我在ModelBuilder 中查看this part of the code 时:

        if(reader.hasClassAnnotation(clazz,XmlTransient.class) || isReplaced) {
            // handle it as if the base class was specified
            r = getClassInfo( nav.getSuperClass(clazz), searchForSuperClass,
                    new ClassLocatable<C>(upstream,clazz,nav) );
        }

似乎ModelBuilder 在类上识别@XmlTransient 并且不考虑它们。因此,在您的 BaseJaxbDoc 上添加 @XmlTransient 可能会有所帮助。

另一种选择是删除BaseJaxbDoc 构造。您使用类继承将编组/解组功能添加到模式派生类。我宁愿将此功能移到一些外部服务中。这可能不是一个选项,因为您可能面临大量遗留代码。

另一种选择是在运行时尝试 MOXy 而不是 JAXB RI。

【讨论】:

  • 再次感谢您花时间帮助我!不幸的是,XMLTransient 并没有帮助 - 由于 BaseJaxbDoc 类中的属性,我最终遇到了更多异常。我很想放弃这个基类,但正如你所说 - 这是很多返工。理想情况下,我会在重新设计之前让所有东西在更新的构建环境中运行。我将再次尝试 MOXy 实现——它需要 Java 1.7+ 才能运行,所以我会看到一些对该实现的引用,我确实尝试过,但在出现更多异常时退出了。我决定看看我是否可以破解@XMLValue 。
  • MOXy 异常:javax.xml.bind.JAXBException:提供程序 org.eclipse.persistence.jaxb.JAXBContextFactory 无法实例化:javax.xml.bind.JAXBException:异常描述:属性或字段值不能用 XmlValue 注释,因为它是另一个 XML 绑定类的子类。 - 带有链接异常:[Exception [EclipseLink-50011] (Eclipse Persistence Services - 2.6.1.v20150605-31e8258): org.eclipse.persistence.exceptions.JAXBException 异常描述:属性或字段值不能用 XmlValue 注释,因为它是另一个 XML 绑定类的子类。]
  • 看起来我别无选择,只能在没有 BaseJaxbDoc 的情况下重新设计模块...。感谢所有帮助,我将花一些时间使用 MOXy 实现来研究这个问题在摆脱 BaseJaxbDoc 之前。
  • OK....我还尝试从绑定文件中删除 XJC:superclass 绑定,它已停止在运行时抛出异常...非常感谢!你已经向我展示了如何停止 rt 异常,太棒了!现在由我来做一些工作并调查这有什么副作用 - 因为单元测试正在编组/解组测试 xml 就好了!非常感谢您今天早上为我抽出时间,希望有一天我能回报您的青睐!
猜你喜欢
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 2019-04-09
  • 2013-03-03
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多