Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-5744

@XmlTransient behavior change in WSDL fault content

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.7.7, 2.7.11, 3.0.1
    • Fix Version/s: 2.7.13, 3.0.2
    • Component/s: JAXB Databinding
    • Labels:
      None
    • Estimated Complexity:
      Unknown

      Description

      We have an exception hierarchy that is exposed in the WSDL. We are explicitly hiding the message field derived from Throwable by adding @XmlTransient to an overridden getter method in our base exception class.

      For versions of CXF prior to 2.7.7, the dynamically-generated WSDL does not contain the message field. For 2.7.7 and later, the field is included in the WSDL fault definition.

      Here's our base exception class:

      package common.exception;
      
      import java.util.Arrays;
      
      import javax.xml.bind.annotation.XmlTransient;
      import javax.xml.ws.WebFault;
      
      import org.apache.commons.lang3.ArrayUtils;
      
      /**
       * Common exception class.
       */
      @WebFault(name = "businessFault", targetNamespace = "http://example.com/common")
      public class BusinessException extends Exception {
      
          /**
           * Default serial version UID.
           */
          private static final long serialVersionUID = 1L;
      
          /**
           * Message to be used for the exception (could be internationalized).
           */
          private String businessMessage;
      
          /**
           * Details associated with the error. These are optional, and can be used as replacement parameters if the error message is a
           * pattern.
           */
          private String[] details;
      
          /**
           * The simple class name of the business error; initially used for type information.
           */
          private String errorType;
      
          /**
           * Initializes an instance of <code>BusinessException</code> with the default data. This constructor must only be used during
           * remote instantiation (such as JAXB unmarshalling).
           */
          public BusinessException() {
              super();
          }
      
          /**
           * Initializes an instance of <code>BusinessException</code> with the provided data. This constructor must only be used when
           * encapsulating a <code>BusinessException</code> not declared in the service API.
           * 
           * @param undeclaredException the exception being encapsulated
           */
          public BusinessException(BusinessException undeclaredException) {
              super(undeclaredException);
              businessMessage = undeclaredException.getBusinessMessage();
              details = undeclaredException.getDetails();
              errorType = undeclaredException.getClass().getSimpleName();
          }
      
          /**
           * Initializes an instance of <code>BusinessException</code> with the provided data.
           * 
           * @param businessMessage the message communicated to clients for this failure; if this is a format pattern, any detail information
           *            provided will be substituted into the pattern for display
           * @param cause the third-party (or non-business) exception to encapsulate
           * @param details associated with the business failure
           * @see String#format(String, Object...)
           */
          public BusinessException(String businessMessage, Exception cause, String... details) {
              super(cause);
              this.businessMessage = businessMessage;
              this.details = details;
              errorType = this.getClass().getSimpleName();
          }
      
          /**
           * Initializes an instance of <code>BusinessException</code> with the provided data.
           * 
           * @param businessMessage the message communicated to clients for this failure; if this is a format pattern, any detail information
           *            provided will be substituted into the pattern for display
           * @param details associated with the business failure
           * @see String#format(String, Object...)
           */
          public BusinessException(String businessMessage, String... details) {
              this(businessMessage, null, details);
          }
      
          /**
           * Retrieves the value for {@link #businessMessage}.
           * 
           * @return the current value
           */
          @XmlTransient
          public String getBusinessMessage() {
              return businessMessage;
          }
      
          /**
           * Retrieves the value for {@link #details}.
           * 
           * @return the current value
           */
          public String[] getDetails() {
              return ArrayUtils.clone(details);
          }
      
          /**
           * Retrieves the value for {@link #errorType}.
           * 
           * @return the current value
           */
          public String getErrorType() {
              return errorType;
          }
      
          /**
           * {@inheritDoc}. Required implementation.
           * 
           * @see java.lang.Throwable#getMessage()
           */
          @Override
          @XmlTransient
          public String getMessage() {
              if (businessMessage != null) {
                  return String.format(businessMessage, (Object[]) details);
              }
              return super.getMessage();
          }
      
          /**
           * Provides a value for {@link #details}.
           * 
           * @param details the new value to set
           */
          public void setDetails(String[] details) {
              if (null != details) {
                  this.details = Arrays.copyOf(details, details.length);
              }
          }
      
          /**
           * Provides a value for {@link #errorType}.
           * 
           * @param errorType the new value to set
           */
          public void setErrorType(String errorType) {
              this.errorType = errorType;
          }
      
          /**
           * Provides a value for {@link #businessMessage}.
           * 
           * @param message the new value to set
           */
          @XmlTransient
          public void setMessage(String message) {
              businessMessage = message;
          }
      }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                dkulp Daniel Kulp
                Reporter:
                ms185252 Michael Schechter
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: