Jaxb Xjc:生成异常的类子类型?

时间:2012-10-11 13:26:08

标签: jaxb xjc

如何使一些xjc生成的类成为自定义Exception的子类,这样你就可以实际抛出它们,并且可以通过JAXBContext进行处理?通常,webservices返回定义的各种故障,这些故障确实应该是一个例外,但是因为它们不是你需要不必要地包装它们。

2 个答案:

答案 0 :(得分:2)

即使您可以创建一个从Exception扩展的JAXB (JSR-222)模型,您也无法从中创建JAXBContext。我建议将Exception包装在与JAXB兼容的域模型中。

Java模型(Foo)

下面是一个扩展Exception的简单Java类。

package forum12840627;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo extends Exception {

}

<强>演示

下面的演示代码尝试在Java模型上创建JAXBContext

package forum12840627;

import javax.xml.bind.JAXBContext;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);
    }

}

<强>输出

以下是运行演示代码返回的异常。问题是Exception不是有效的JAXB类,而JAXB实现在处理Java模型时会引入超类。 (注意:在您自己的域模型中,您可以使用@XmlTransient注释超级类以防止它们被处理:http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html

Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
    this problem is related to the following location:
        at java.lang.StackTraceElement
        at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
        at java.lang.Throwable
        at java.lang.Exception
        at forum12840627.Foo

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
    at forum12840627.Demo.main(Demo.java:8)

更新#1

如果您使用EclipseLink JAXB(MOXy)作为JAXB提供程序,那么您将看不到此异常,因为javax.*java.*包中的类不被视为域类。 MOXy是WebLogic 12c环境中的默认JAXB提供程序,或者可以使用jaxb.properties文件进行配置。

了解更多信息

更新#2

最新版本的JAXB参考实现似乎现在处理这个用例以及MOXy。我原来的可移植性问题可能不是一个问题。

答案 1 :(得分:1)

是的,我终于找到了一些东西! Inheritance plugin能够使生成的类继承自类或实现其他接口。

您需要包含类似

的内容
  <bindings node="//xsd:complexType[@name='WhateverException']">
    <inheritance:extends>foo.bar.WhateverException</inheritance:extends>
  </bindings>

进入绑定文件并覆盖getStackTrace()以返回null,以便它不会被编组。

不幸的是,您可能会遇到一些JAXB实现的问题(请参阅Blaise Doughan's answer) - 我还没有找到解决方法。因此,您可以使用不太不可移植的解决方案,也可以将JAXB对象包装到Exceptions中。