[
https://issues.apache.org/jira/browse/CXF-5744?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Michael Schechter updated CXF-5744:
-----------------------------------
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:
{code}
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;
}
}
{code}
was:
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 overriden 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:
{code}
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;
}
}
{code}
> @XmlTransient behavior change in WSDL fault content
> ---------------------------------------------------
>
> Key: CXF-5744
> URL: https://issues.apache.org/jira/browse/CXF-5744
> Project: CXF
> Issue Type: Bug
> Components: JAXB Databinding
> Affects Versions: 2.7.7, 2.7.11
> Reporter: Michael Schechter
> Priority: Minor
>
> 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:
> {code}
> 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;
> }
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.2#6252)