2017-11-22 3 views
2

Ich stieß vor kurzem auf ein Problem mit einer unserer älteren Anwendungen, die von der UPS Tracking API abhängig ist. UPS änderte ihre Kommunikationsprotokolle, um TLSv1.2 zu benötigen. Unglücklicherweise scheint die neueste öffentliche Version von jdk 1.6 dieses Protokoll nicht zu unterstützen, also bestand meine Option darin, für einen Oracle Supportvertrag zu bezahlen oder auf jdk 1.7 aufzurüsten. Ich ging mit dem Upgrade auf 1.7Der Wechsel von Java 1.6 zu 1.7 verursacht JAXB Exception

Ich änderte die Abhängigkeiten für mein Projekt und alles sah gut aus. Als ich versuchte, zu implementieren tatsächlich auf den Anwendungsserver ist fehlgeschlagen mit dem Fehler:

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.lang.StackTraceElement does not have a no-arg default constructor

Ich habe einige Nachforschungen und offenbar ist das Problem verursacht durch jaxb Methoden @WebMethod kommentiert, die eine Ausnahme mit throwable werfen. Die Lösung dafür (ich dachte) war, der Ausnahmeklasse eine @WebFault Annotation hinzuzufügen. Ich folgte den Anweisungen hier: http://java.globinch.com/enterprise-java/web-services/jax-ws/jax-ws-exceptions-faults-annotation-exception-and-fault-handling-examples/ und re-implementiert.

Das Ergebnis war der gleiche Fehler. Der einzige Unterschied ist, dass mein Stacktrace angibt, dass es meine benutzerdefinierte Fehlerbohne verwendet, anstatt zu versuchen, einen Wrapper zu generieren. Ich habe mir auch die Lösungen angesehen, die hier gegeben werden: map exceptions to faults und soweit ich sagen kann, erfüllen meine Klassen die Spezifikation, aber das Problem bleibt bestehen.

Dieses Problem verhindert, dass ich die USV-Probleme beheben kann und meinen Benutzern große Kopfschmerzen bereitet. Jede Hilfe würde sehr geschätzt werden.

Mein Error Log

Caused by: org.jboss.ws.WSException: Failed to create JAXBContext at jaxb.hibernate.XMLAcccesorAvailableContextFactory.createContext(XMLAcccesorAvailableContextFactory.java:41) at org.jboss.ws.metadata.builder.jaxws.JAXWSMetaDataBuilder.createJAXBContext(JAXWSMetaDataBuilder.java:940) ... 82 more Caused by: 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 private java.lang.Throwable[] com.tura.common.server.service.addressvalidation.AddressServiceFault.suppressed at com.tura.common.server.service.addressvalidation.AddressServiceFault

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

die Exception-Klasse

@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; 
    } 
} 

Die Fehler Bean Klasse

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; 
    } 
} 

Meine WebService-Klasse

@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(); 
    } 
+0

Mögliches Duplikat von [JAX-WS - Map-Ausnahmen zu Fehlern] (https://StackOverflow.com/questions/2064447/jax-ws-map-exceptions-to-faults) – Optional

+0

Java 6 unterstützt jetzt TLS 1.2, siehe unten http://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121 –

+0

@ LAKHDAR Omar Ich bin mir bewusst, dass es eine Version von Java 6, die TLSv1.2 unterstützt. Leider sind diese Versionen des JDK nicht öffentlich verfügbar, die mir bekannt sind. Der einzige Weg, sie zu bekommen, ist mit einem bezahlten Supportvertrag mit Oracle. Wenn ich falsch liege und es eine seriöse Möglichkeit gibt, Zugang zu den neueren Versionen des Java 6 jdk zu bekommen, lass es mich wissen. – pbuchheit

Antwort

1

Sieht so aus als hätte niemand rechtzeitig eine Lösung gefunden, also werde ich weitermachen und posten, wie ich das behoben habe. JAX-WS verwendet Reflektion, um zu bestimmen, ob eine Ausnahmeklasse umgebrochen werden soll oder nicht. Daher ist es SEHR wählerisch, welche Konstruktoren und Methoden in der Exception enthalten sind.Wenn Sie an der Klasse AddressValidationServiceException der Nähe betrachten, werden Sie feststellen, dass es diese Methode hat:

protected AddressServiceFault getFaultInfo() { 
     return faultInfo; 
    } 

Das Problem ist in der Sichtbarkeit dieser Methode. getFaultInfo() MUSS eine public Methode sein, sonst wird jax-ws die Ausnahmeklasse nicht korrekt erkennen und umbrechen. Sobald ich diese Methode auf die Öffentlichkeit übertrug, fing alles an zu arbeiten. Tatsächlich konnte ich die @WebFault Annotation vollständig entfernen. Solange die Ausnahmeklasse und der Fehler korrekt formatiert sind, wird die explizite Anmerkung nicht benötigt.

Ein weiterer "Gotcha" zu beachten. Java-Konstruktoren werden nicht vererbt. Wenn Sie weitere Klassen, die Ihre Ausnahme verlängern, muss jede Klasse in der Hierarchie explizit definieren die

public MyClass(String message, MyServiceFault fault) 

und

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

Bauer.

0

Es scheint, wie Ihre Exception-Klasse braucht getStackTrace() und getCause() -Methode außer Kraft zu setzen. Werfen Sie einen Blick here, könnte die Antwort von Domenic D. die Lösung sein.

Möglicherweise gibt es ein Problem mit der jaxb-impl-Version, die ebenfalls beschrieben wird.

0

Throwable-Objekte können nicht direkt in XML serialisiert werden, da das StackTraceElement über keinen Konstruktor für Argumente verfügt, der von JAXB benötigt wird.

Verwenden Sie benutzerdefinierten SOAP-Fehler (Klasse mit @WebFault Annotated) und senden Sie die Ausnahme Details mit Detailelement unter soapFault.

+0

Danke für den Vorschlag, aber wenn Sie wieder auf den Code schauen, den ich gepostet habe, ist genau das, was ich mache. – pbuchheit

+0

Ich kann Code nicht sehen, wo Sie AddressServiceFault und dann in AddressValidationServiceException auffüllen und dann die AddressValidationServiceException werfen. In der Methode Ihres Dienstes getValidAddressXMLByLocation die Ausnahme abfangen, AddressServiceFault auffüllen und in AddressValidationServiceException setzen und dann werfen, wird es funktionieren –

+0

Ich aktualisierte das Beispiel, um den Code aufzunehmen, wo die Ausnahme tatsächlich ausgelöst wird. Das Auffüllen und Werfen der Ausnahme scheint nicht die Ursache zu sein. – pbuchheit

Verwandte Themen