[ 
https://issues.apache.org/jira/browse/CXF-4016?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Daniel Kulp reassigned CXF-4016:
--------------------------------

    Assignee: Daniel Kulp
    
> JAX-WS schema generation of an Exception annoted with @WebFault that contains 
> a property of a class annotated with @XmlRootElement causes the schema of the 
> WSDL to generate the incorrectly
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CXF-4016
>                 URL: https://issues.apache.org/jira/browse/CXF-4016
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-WS Runtime
>    Affects Versions: 2.4
>            Reporter: Vincent Furlanetto
>            Assignee: Daniel Kulp
>
> I have the following Exception Class (BusinessException) that is annotated 
> with @WebFault.  BusinessException has a property named exceptionMessage that 
> is of Type ExceptionMessage. ExceptionMessage is annotated with the 
> @XmlRootElement annotation.
> When CXF generates the WSDL via hitting the web wervice URL it generates a 
> schema with an invalid element for the BusinessException element.
> See the schema in question here:
> {code}
> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" 
> targetNamespace="http://www.mycompany.com/platform/exception"; 
> xmlns:tns="http://www.mycompany.com/platform/exception"; 
> xmlns:xs="http://www.w3.org/2001/XMLSchema";>
> <xs:element name="ExceptionMessage" type="tns:exceptionMessage"/>
> <xs:complexType name="exceptionMessage">
> <xs:sequence>
> <xs:element minOccurs="0" name="classCause" type="xs:string"/>
> <xs:element minOccurs="0" name="severity" type="xs:string"/>
> <xs:element minOccurs="0" name="exceptionMessage" type="xs:string"/>
> <xs:element minOccurs="0" name="displayMessage" type="xs:string"/>
> <xs:element name="code" type="xs:int"/>
> <xs:element minOccurs="0" name="informationCode" type="xs:string"/>
> <xs:element minOccurs="0" name="uniqueID" type="xs:string"/>
> <xs:element minOccurs="0" name="userResolution" type="xs:string"/>
> <xs:element minOccurs="0" name="exceptionCause" type="xs:string"/>
> <xs:element minOccurs="0" name="stack" type="xs:string"/>
> </xs:sequence>
> </xs:complexType>
> <xs:complexType name="BusinessException">
> <xs:sequence>
> <xs:element nillable="true"/>
> </xs:sequence>
> </xs:complexType>
> <xs:element name="BusinessException" type="tns:BusinessException"/>
> </xs:schema>
> {code}
> Notice this portion of the schema here:
> {code}
> <xs:complexType name="BusinessException">
> <xs:sequence>
> <xs:element nillable="true"/>
> </xs:sequence>
> </xs:complexType>
> {code}
> It is generating an invalid schema element "<xs:element nillable="true"/>" 
> without a name or ref.
> The problem appears to be with the fact that the ExceptionMessage class is 
> annotated with @XmlRootElement.  If I remove the @XmlRootElement from the 
> ExceptionMessage class it all works fine.  My problem is that the 
> ExceptionMessage class is also used by other services in my code that need to 
> serialize the ExceptionMessage to xml via JAXB.  And as I'm sure you already 
> know when using the JaxbContext will throw an Exception if the class is not 
> annotated with the @XmlRootElement.  I have been able to work around this 
> issue by simply removing the @XmlRootElement annotation and programmatically 
> implementing a JAXBElement object which will then allow me to use the 
> JaxbContext without getting the non present @XmlRootElement Exception.
> {code}
>       QName qName = new QName("http://www.mycompany.com/platform/exception";, 
> "ExceptionMessage");
>       JAXBElement<ExceptionMessage> jaxbElement = new 
> JAXBElement<ExceptionMessage>(qName, ExceptionMessage.class, 
> exceptionMessageObj);
> {code}
> So I guess what I'm asking is isn't it possible just use the simple class 
> name for the WSDL schema name  for a class that is annotated with 
> @XmlRootElement verus generating an invalid schema element without a name or 
> ref? 
> Please see the code example below:
> {code}
> package com.mycompany.platform.exception.checked;
> import java.io.Serializable;
> import javax.xml.ws.WebFault;
> /**
>  * <code>BusinessException</code>-
>  * 
>  * Base class for business exceptions. It is only used by application 
> developer.
>  * Caller should have knowledge about how to handle this exception.
>  * 
>  */
> @WebFault(name = "BusinessException", targetNamespace = 
> AbstractException.TARGET_NAMESPACE)
> public class BusinessException extends AbstractException {
>       /**
>        * The exception message
>        */
>       private ExceptionMessage exceptionMessage;
>       /**
>        * Serial Version ID to compare if the class version has changed in
>        * serialization/deserialization.
>        */
>       private static final long serialVersionUID = -4466271192745954077L;
>       /**
>        * Default logical exception code
>        */
>       private static final String INFO_CODE = "error.business";
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final Throwable nested) {
>               super(nested);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final String msg, final Throwable nested,
>                       final String newInfoCode, final Serializable... args) {
>               super(msg, nested, newInfoCode, args);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final String msg, final String newInfoCode,
>                       final Serializable... args) {
>               super(msg, newInfoCode, args);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final String msg, final Throwable nested) {
>               super(msg, nested);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final Throwable nested, final String 
> newInfoCode) {
>               super(nested, newInfoCode);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException(final String msg) {
>               super(msg);
>       }
>       /**
>        * @see com.mycompany.platform.exception.checked.AbstractException
>        */
>       public BusinessException() {
>               super();
>       }
>       /**
>        * <code>getDefaultInformationCode</code>-
>        * 
>        * Returns the default exception key to use if none is specified when 
> the
>        * exception is thrown.
>        * 
>        * @return <code>String</code> default information code
>        */
>       @Override
>       public String getDefaultInformationCode() {
>               return INFO_CODE;
>       }
>       
>       public ExceptionMessage getExceptionMessage() {
>               return exceptionMessage;
>       }
>       public void setExceptionMessage(final ExceptionMessage 
> exceptionMessage) {
>               this.exceptionMessage = exceptionMessage;
>       }
> }
> package com.mycompany.platform.exception.checked;
> import javax.xml.bind.annotation.XmlRootElement;
> import javax.xml.bind.annotation.XmlType;
> /**
>  *
>  * <code>ExceptionMessage</code>-
>  *
>  * The ExceptionMessage object that is used in the application to create
>  * and utilize error messages. This object provides methods to create an
>  * ExceptionMessage object and setters/getters for its various attributes.
>  *
>  */
> @XmlRootElement(name = "ExceptionMessage")
> @XmlType(propOrder = {
>     "classCause",
>     "severity",
>     "exceptionMessage",
>     "displayMessage",
>     "code",
>     "informationCode",
>     "uniqueID",
>     "userResolution",
>     "exceptionCause",
>     "stack"
> })
> public class ExceptionMessage {
>     /**
>      * WARN <code>String</code> definition
>      */
>     public static final String WARN = "WARN";
>     /**
>      * DEBUG <code>String</code> definition
>      */
>     public static final String DEBUG = "DEBUG";
>     /**
>      * ERROR <code>String</code> definition
>      */
>     public static final String ERROR = "ERROR";
>     /**
>      * FATAL <code>String</code> definition
>      */
>     public static final String FATAL = "FATAL";
>     /**
>      * INFO <code>String</code> definition
>      */
>     public static final String INFO = "INFO";
>     /**
>      * PERIOD <code>String</code> definition.  Generates a new line.
>      */
>     private static final String PERIOD = ".\n";
>     private String displayMessage;
>     private String severity;
>     private String informationCode;
>     private String userResolution;
>     private String uniqueID;
>     private String stack;
>     private String exceptionCause;
>     private String exceptionMsg;
>     private String classCause;
>     private int code;
>     /**
>      * Creates a new <code>ExceptionMessage</code> object.
>      */
>     public ExceptionMessage() {
>         super();
>     }
>     /**
>      * Creates a new <code>ExceptionMessage</code> object.
>      *
>      * @param informationCode <code>String<code> information code
>      * @param theMessage <code>String</code> textual error message
>      * @param theCode <code>String</code> error message code
>      * @param theSeverity <code>String</code> error severity
>      * @param theUserResolution <code>String</code> user resolution
>      */
>     public ExceptionMessage(final String informationCode,
>             final String theMessage, final int theCode,
>             final String theSeverity, final String theUserResolution) {
>         this.displayMessage = theMessage.replace("\"", "");
>         this.code = theCode;
>         this.severity = theSeverity;
>         this.informationCode = informationCode;
>         this.userResolution = theUserResolution.replace("\"", "");
>     }
>       public void setInformationCode(String informationCode) {
>               this.informationCode = informationCode;
>       }
>       public void setUserResolution(String userResolution) {
>               this.userResolution = userResolution.replace("\"", "");
>       }
>     /**
>      * <code>getClassCause</code>-
>      * Returns the <code>String<code> Class name that caused the exception.
>      *
>      * @return <code>String<code> Class name that caused the exception
>      */
>     public String getClassCause() {
>               return classCause;
>       }
>       /**
>        * <code>setClassCause</code>-
>        * Sets the <code>String<code> Class name that caused the exception.
>        *
>        * @param classCause <code>String<code> Class name that caused the 
> exception
>        */
>       public void setClassCause(String classCause) {
>               this.classCause = classCause;
>       }
>     /**
>      * <code>setCode</code>-
>      *
>      * Sets the code.
>      *
>      * @param theCode <code>int</code> to set
>      *
>      */
>     public void setCode(final int theCode) {
>         this.code = theCode;
>     }
>     /**
>      * <code>getCode</code>-
>      *
>      * Returns the code.
>      *
>      * @return <code>int<code> code
>      */
>     public int getCode() {
>         return this.code;
>     }
>     /**
>      * <code>setDisplayMessage</code>-
>      *
>      * Sets the message.
>      *
>      * @param aDisplayMessage <code>String</code> to set
>      *
>      */
>     public void setDisplayMessage(final String aDisplayMessage) {
>         this.displayMessage = aDisplayMessage.replace("\"", "");
>     }
>     /**
>      * <code>getDisplayMessage</code>-
>      *
>      * Returns the message.
>      *
>      * @return <code>String</code> display message
>      */
>     public String getDisplayMessage() {
>         return this.displayMessage;
>     }
>     /**
>      * <code>setSeverity</code>-
>      *
>      * Sets the severity.
>      *
>      * @param theSeverity <code>String</code> to set
>      *
>      */
>     public void setSeverity(final String theSeverity) {
>         this.severity = theSeverity;
>     }
>     /**
>      * <code>getSeverity</code>-
>      *
>      * Returns the severity.
>      *
>      * @return <code>String</code> severity
>      */
>     public String getSeverity() {
>         return this.severity;
>     }
>     /**
>      * <code>getInformationCode</code>-
>      *
>      * Returns the logicalName
>      *
>      * @return <code>String</code> information code
>      *
>      */
>     public String getInformationCode() {
>         return this.informationCode;
>     }
>     /**
>      * <code>getUserResolution</code>-
>      *
>      * Returns the userResolution.
>      *
>      * @return <code>String</code> user resolution
>      *
>      */
>     public String getUserResolution() {
>         return this.userResolution;
>     }
>     /**
>      * <code>getUniqueID</code>-
>      *
>      * Returns the unique id for the exception
>      *
>      * @return <code>String</code> Unique ID
>      */
>     public String getUniqueID() {
>         return this.uniqueID;
>     }
>     /**
>      * <code>setUniqueID</code>-
>      *
>      * Sets the unique id for the exception
>      *
>      * @param uniqueID <code>String</code> to set
>      */
>     public void setUniqueID(final String uniqueID) {
>         this.uniqueID = uniqueID;
>     }
>     /**
>      * <code>getStack</code>-
>      *
>      * Gets the stack trace of the exception that occurred
>      *
>      * @return <code>String</code> containing exception stack
>      */
>     public String getStack() {
>         return stack;
>     }
>     /**
>      * <code>setStack</code>-
>      * Sets the stack trace of the exception that occurred
>      *
>      * @param stackTraceElements <code>String</code> representation of the 
> stack to set
>      *
>      */
>     public void setStack(
>             final String stack) {
>               this.stack = stack;
>     }
>     /**
>      * <code>setStackTrace</code>-
>      * Sets the stack trace of the exception that occurred
>      *
>      * @param stackTraceElements <code>StackTraceElement</code> array to set
>      *
>      */
>     public void setStackTrace(
>             final StackTraceElement[] stack) {
>       if (stack != null)
>       {
>               StringBuilder builder = new StringBuilder();
>               this.stack = ExceptionMessage.convert(builder, 
> stack).toString();
>       }
>     }
>     /**
>      * <code>getExceptionCause</code>-
>      *
>      * This method returns the original exception cause. A cause is another
>      * <code>Throwable</code> that caused the final exception to be thrown.
>      *  It is also known as the chained exception facility, as the cause can,
>      * itself, have a cause, and so on,
>      * leading to a "chain" of exceptions, each caused by another. Please note
>      * that this cause may return null if no cause was set using the @see
>      * {@link ExceptionMessage.setExceptionCause()} method.
>      *
>      * @return <code>String</code> representation of the 
> <code>Throwable</code> chained that was set
>      */
>     public String getExceptionCause() {
>         return this.exceptionCause;
>     }
>     /**
>      * <code>setExceptionCause</code>-
>      *
>      * This method sets the original exception cause. A cause is another
>      * <code>Throwable</code> that caused the final exception to be thrown. 
> The cause
>      * facility was added new in release 1.4. It is also known as the chained
>      * exception facility, as the cause can, itself, have a cause, and so on,
>      * leading to a "chain" of exceptions, each caused by another. this is
>      * OPTIONAL value and only to be used if there is a strong need to display
>      * the cause of the exception.
>      *
>      * @param exceptionCause <code>String</code> representation of 
> <code>Throwable</code> chained exception to set
>      */
>     public void setExceptionCause(final String exceptionCause) {
>         this.exceptionCause = exceptionCause;
>     }
>     /**
>      * <code>setExceptionCausing</code>-
>      *
>      * This method sets the original exception cause. A cause is another
>      * <code>Throwable</code> that caused the final exception to be thrown. 
> The cause
>      * facility was added new in release 1.4. It is also known as the chained
>      * exception facility, as the cause can, itself, have a cause, and so on,
>      * leading to a "chain" of exceptions, each caused by another. this is
>      * OPTIONAL value and only to be used if there is a strong need to display
>      * the cause of the exception.
>      *
>      * @param exceptionCause <code>Throwable</code> exception to set
>      */
>     public void setExceptionCausing(final Throwable exceptionCausing) {
>         this.exceptionCause = exceptionCausing.toString();
>     }
>     /**
>      * <code>getExceptionMessage</code>-
>      *
>      * Returns the detail message string of this throwable. The detail message
>      * string of this <code>Throwable</code> instance (which may be null).
>      *
>      * @return <code>String</code> exceptionMessage
>      */
>     public String getExceptionMessage() {
>         return this.exceptionMsg;
>     }
>     /**
>      * <code>setExceptionMessage</code>-
>      *
>      * Sets the detail message string of the <code>Throwable<code> that the 
> exception
>      * message may use to display. this is optional and may not always be set.
>      *
>      * @param exceptionMessage <code>String</code> exception message to set.
>      *
>      */
>     public void setExceptionMessage(final String exceptionMessage) {
>         this.exceptionMsg = exceptionMessage;
>     }
>     /* (non-Javadoc)
>      * @see java.lang.Object#toString()
>      */
>     @Override
>     public String toString() {
>         final StringBuilder stringBuilder = new StringBuilder();
>         stringBuilder.append("Unique ID: ");
>         stringBuilder.append(this.uniqueID);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Information Code: ");
>         stringBuilder.append(this.informationCode);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Error Code: ");
>         stringBuilder.append(this.code);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("User Message: ");
>         stringBuilder.append(this.displayMessage);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Message: ");
>         stringBuilder.append(this.exceptionMsg);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Resolution: ");
>         stringBuilder.append(this.userResolution);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Exception Class: ");
>         stringBuilder.append(this.classCause);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Detailed Stack Trace: ");
>         stringBuilder.append(this.stack);
>         stringBuilder.append(PERIOD);
>         stringBuilder.append("Cause: ");
>         stringBuilder.append(this.exceptionCause);
>         return stringBuilder.toString();
>     }
>     /**
>      * <code>convert</code>-
>      *
>      * Converts the stack trace of an exception into 
> <code>StringBuilder</code> from <code>StackTraceElement</code>.
>      *
>      * @param newStringBuilder <code>StringBuilder</code> buffer to which 
> will be appended
>      * @param stack <code>StackTraceElement</code> array of elements to 
> append to the stack
>      *
>      * @return <code>StringBuilder</code> of the exception stack trace
>      */
>     public static StringBuilder convert(final StringBuilder newStringBuilder,
>             final StackTraceElement[] stack) {
>         StringBuilder result = newStringBuilder;
>         if (stack != null && stack.length > 0) {
>             if (result == null) {
>                 result = new StringBuilder();
>             }
>             result.append(stack[0]);
>             for (int i = 1; i < stack.length; i++) {
>                 result.append('\n');
>                 result.append(stack[i]);
>             }
>         } else {
>             if (result == null) {
>                 result = new StringBuilder();
>             }
>         }
>         return result;
>     }
> }
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to