现在已经解决了大约半个星期的问题,需要帮助,因为我似乎无法取得任何进展。
我继承了一个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转换,剥离注释并创建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 marshall / unmarshall类以及其他一些辅助函数。 所以我的问题是当我无法修改架构时如何解决这个异常? XSLT中的东西还是绑定文件中的东西?
My Maven依赖项: 对于JAXB: org.jvnet.jaxb2.maven2 Maven的jaxb21-插件 0.13.0
JAXB运行时: org.glassfish.jaxb JAXB运行时 2.2.11
答案 0 :(得分:1)
尝试使用BaseJaxbDoc
注释@XmlTransient
。
您遇到的问题是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
并且不考虑它们。因此,@XmlTransient
对BaseJaxbDoc
BaseJaxbDoc
提供帮助的机会很有帮助。
另一个选择是删除 $source = null;
$default = 'something';
if(isset($request['controller']['options']['data']['source']) && !empty($request['controller']['options']['data']['source'])) {
$source = $request['controller']['options']['data']['source'];
} else {
$source = $default;
}
构造。您可以使用类继承向模式派生类添加编组/解组功能。我宁愿将此功能移到某些外部服务中。这可能不是一个选项,因为您可能面临很多遗留代码。
另一个选择是在运行时尝试MOXy而不是JAXB RI。