从Java 1.6切换到1.7会导致JAXB异常

时间:2017-11-22 20:37:17

标签: java jboss jaxb tls1.2

我最近遇到了一个依赖于UPS Tracking API的遗留应用程序的问题。 UPS改变了他们的通信协议以要求TLSv1.2。不幸的是,jdk 1.6的最新公共版本似乎不支持这个协议,所以我的选择是支付oracle支持合同或升级到jdk 1.7。我升级到1.7

我更改了项目的依赖项,一切看起来都很好。当我尝试实际部署到应用程序服务器时,它失败并出现错误:

  

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:1   java.lang.StackTraceElement的IllegalAnnotationExceptions计数   没有no-arg默认构造函数

我做了一些研究,显然这个问题是由jaxb @WebMethod带注释的方法引起的,这些方法使用 throwable 抛出异常。 (我认为)的解决方案是在异常类中添加@WebFault批注。我按照这里的说明操作:http://java.globinch.com/enterprise-java/web-services/jax-ws/jax-ws-exceptions-faults-annotation-exception-and-fault-handling-examples/ 并重新部署。

结果是同样的错误。唯一的区别是我的stacktrace表明它正在使用我的自定义故障bean而不是尝试生成包装器。我也查看了这里给出的解决方案:map exceptions to faults并且据我所知,我的课程符合规范,但问题仍然存在。

此问题阻止我修复UPS问题并导致用户头痛。任何帮助将不胜感激。

我的错误记录

  

引起:org.jboss.ws.WSException:无法在以下位置创建JAXBContext   jaxb.hibernate.XMLAcccesorAvailableContextFactory.createContext(XMLAcccesorAvailableContextFactory.java:41)     在   org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilder.createJAXBContext(JAXWSMetaDataBuilder.java:940)     ... 82更多引起:    com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:1计数   IllegalAnnotationExceptions java.lang.StackTraceElement没有   一个无参数的默认构造函数。这个问题与此有关   以下位置:at public的java.lang.StackTraceElement   java.lang.StackTraceElement [] java.lang.Throwable.getStackTrace()at   java.lang.Throwable私有java.lang.Throwable []   com.tura.common.server.service.addressvalidation.AddressServiceFault.suppressed         在   com.tura.common.server.service.addressvalidation.AddressServiceFault

     

在   com.sun.xml.bind.v2.runtime.IllegalAnnotationsException $ Builder.check(IllegalAnnotationsException.java:106)

异常类

@WebFault(faultBean = "com.tura.common.server.service.addressvalidation.AddressServiceFault")
public class AddressValidationServiceException extends Exception {

    private AddressServiceFault faultInfo;

    public AddressValidationServiceException() {
        super();
    }
    public AddressValidationServiceException(AddressServiceFault fault) {
        super(fault.getFaultString());
        this.faultInfo = fault;
    }

    public AddressValidationServiceException(String message, AddressServiceFault fault) {
        super(message);
        this.faultInfo = fault;
    }

    public AddressValidationServiceException(String message, Throwable cause) {
        super(message, cause);
    }

    public AddressValidationServiceException(String message, AddressServiceFault fault, Throwable cause) {
        super(message, cause);
        this.faultInfo = fault;
    }

    protected AddressServiceFault getFaultInfo() {
        return faultInfo;
    }
}

Fault Bean类

public class AddressServiceFault {

    private String faultCode;

    private String faultString;

    protected String getFaultCode() {
        return faultCode;
    }

    protected void setFaultCode(String faultCode) {
        this.faultCode = faultCode;
    }

    protected String getFaultString() {
        return faultString;
    }

    protected void setFaultString(String faultString) {
        this.faultString = faultString;
    }
}

我的WebService类

@WebMethod
    public @WebResult(name = "validatedAddresses") String parseAddressStringByLocation(
            @WebParam(name = "sLocation") String sLocation) throws AddressValidationServiceException {
        StringBuffer sbUrl = new StringBuffer();
        StringBuffer sbQueryString = new StringBuffer();

        sbUrl.append("http://test.foo.com");

        try {
            sbQueryString.append("&location=");
            sbQueryString.append(URLEncoder.encode(sLocation, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            AddressServiceFault serviceFault = new AddressServiceFault();
            serviceFault.setMessage("Validation Failed");
            throw new AddressValidationServiceException("Address Validation Error: parseQueryStringByLocation.",
                    serviceFault, e);
        }

        sbUrl.append(sbQueryString);

        return sbUrl.toString();
    }

3 个答案:

答案 0 :(得分:2)

看起来没有人及时提出解决方案,所以我会继续发布如何解决这个问题。 JAX-WS使用反射来确定是否应该包装异常类。因此,对于异常中包含的构造函数和方法非常挑剔。如果你仔细看看 AddressValidationServiceException 类,你会发现它有这个方法:

protected AddressServiceFault getFaultInfo() {
        return faultInfo;
    }

问题在于该方法的可见性。 getFaultInfo()必须是 public 方法,否则jax-ws将无法正确识别并包装异常类。一旦我将该方法改为公开,一切都开始起作用了。事实上,我完全可以删除@WebFault注释。只要异常类和错误的格式正确,就不需要显式注释。

另一个'陷阱'要注意。 Java构造函数不是继承的。如果您有其他扩展异常的类,则层次结构中的每个类都必须明确定义

public MyClass(String message, MyServiceFault fault)

public MyClass(String message, MyServiceFault fault, Throwable cause)

构造

答案 1 :(得分:0)

看起来你的Exception类需要覆盖getStackTrace()和getCause()方法。 看看here,Domenic D.的答案可能是解决方案。

jaxb-impl版本可能存在问题,也会对此进行描述。

答案 2 :(得分:0)

由于StackTraceElement没有无参数构造函数,因此无法将Throwable对象直接序列化为XML,这是JAXB所必需的。

使用自定义SOAP错误(使用@WebFault注释的类)并使用soapFault下的detail元素发送异常详细信息。