【问题标题】:Jaxb Xjc: make generated classes subtype of Exception?Jaxb Xjc:使生成的类成为异常的子类型?
【发布时间】:2012-10-11 13:26:07
【问题描述】:

如何使一些 xjc 生成的类成为自定义异常的子类,这样您就可以实际抛出它们,并且可以由 JAXBContext 处理?通常 web 服务会返回各种定义的错误,这些错误确实应该是一个异常,但由于它们不是你需要不必要地包装它们。

【问题讨论】:

    标签: jaxb xjc


    【解决方案1】:

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

    Java 模型(Foo)

    下面是一个简单的 Java 类,它扩展了 Exception

    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。我最初的可移植性问题可能不是什么大问题。

    【讨论】:

    • 感谢您的回答!使用普通的 JDK6 是对的。奇怪的是,在我们的项目中 JAXBContext.newInstance 并没有抛出(可能是因为我们包含了一些 XML 库。)因此,在我们的设置中,您只需覆盖 getStackTrace() 以返回 null,然后您就可以成功地编组和解组异常。 (也许还可以为 StacktraceElement 编写一个 XmlAdapter 以避免在普通 JDK6 上出现这个问题。)所以问题仍然是如何使 xjc 子类成为自定义异常类型。
    • @hstoerr - 您可能正在使用 MOXy 作为您的 JAXB 提供程序(请参阅我的更新)。
    • 对于我当前的 JAXB 提供程序,它仍然可以工作,但我对使用非便携式解决方案犹豫不决。您是否看到了一种将 XmlAdapter 配置为 StacktraceElement(应该被忽略)或其他方式来避免在普通 JDK6 上出现此问题的方法?我没有做到这一点。 :-(
    • @hstoerr - 我已经更新了我的答案。似乎这个用例在最新版本的 JAXB RI 和 MOXy 中都有效。我无法获得适用于此用例的 XmlAdapter 解决方案。
    【解决方案2】:

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

    你需要包含类似的东西

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

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

    不幸的是,您可能会遇到一些 JAXB 实现的麻烦(请参阅Blaise Doughan's answer) - 我还没有找到解决方法。因此,您可以使用不太便携的解决方案,或者将 JAXB 对象包装到异常中。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多