Return-Path: X-Original-To: apmail-cxf-issues-archive@www.apache.org Delivered-To: apmail-cxf-issues-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 86C14950E for ; Fri, 13 Jan 2012 21:31:07 +0000 (UTC) Received: (qmail 37160 invoked by uid 500); 13 Jan 2012 21:31:07 -0000 Delivered-To: apmail-cxf-issues-archive@cxf.apache.org Received: (qmail 37147 invoked by uid 500); 13 Jan 2012 21:31:06 -0000 Mailing-List: contact issues-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list issues@cxf.apache.org Received: (qmail 37137 invoked by uid 99); 13 Jan 2012 21:31:06 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jan 2012 21:31:06 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jan 2012 21:31:02 +0000 Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116]) by hel.zones.apache.org (Postfix) with ESMTP id 369BF14A8DC for ; Fri, 13 Jan 2012 21:30:40 +0000 (UTC) Date: Fri, 13 Jan 2012 21:30:40 +0000 (UTC) From: "Daniel Kulp (Resolved) (JIRA)" To: issues@cxf.apache.org Message-ID: <2083946714.39311.1326490240225.JavaMail.tomcat@hel.zones.apache.org> In-Reply-To: <424524693.23540.1326150099505.JavaMail.tomcat@hel.zones.apache.org> Subject: [jira] [Resolved] (CXF-4016) 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/CXF-4016?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Daniel Kulp resolved CXF-4016. ------------------------------ Resolution: Fixed Fix Version/s: 2.5.2 2.4.6 Fixed. Two comments: 1)While writing my test, I was actually getting an Exception thrown instead of the element without a type. Might be a difference on trunk/2.6 though. 2) You could likely work around this by adding a name="ExceptionMessage" attribute to the @XmlType annotation to make it generate the type as a top level type, not an anonymous type in an element. > 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 > Fix For: 2.4.6, 2.5.2 > > > 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} > > > > > > > > > > > > > > > > > > > > > > > > {code} > Notice this portion of the schema here: > {code} > > > > > > {code} > It is generating an invalid schema element "" 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 jaxbElement = new JAXBElement(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; > /** > * BusinessException- > * > * 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(); > } > /** > * getDefaultInformationCode- > * > * Returns the default exception key to use if none is specified when the > * exception is thrown. > * > * @return String 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; > /** > * > * ExceptionMessage- > * > * 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 String definition > */ > public static final String WARN = "WARN"; > /** > * DEBUG String definition > */ > public static final String DEBUG = "DEBUG"; > /** > * ERROR String definition > */ > public static final String ERROR = "ERROR"; > /** > * FATAL String definition > */ > public static final String FATAL = "FATAL"; > /** > * INFO String definition > */ > public static final String INFO = "INFO"; > /** > * PERIOD String 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 ExceptionMessage object. > */ > public ExceptionMessage() { > super(); > } > /** > * Creates a new ExceptionMessage object. > * > * @param informationCode String information code > * @param theMessage String textual error message > * @param theCode String error message code > * @param theSeverity String error severity > * @param theUserResolution String 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("\"", ""); > } > /** > * getClassCause- > * Returns the String Class name that caused the exception. > * > * @return String Class name that caused the exception > */ > public String getClassCause() { > return classCause; > } > /** > * setClassCause- > * Sets the String Class name that caused the exception. > * > * @param classCause String Class name that caused the exception > */ > public void setClassCause(String classCause) { > this.classCause = classCause; > } > /** > * setCode- > * > * Sets the code. > * > * @param theCode int to set > * > */ > public void setCode(final int theCode) { > this.code = theCode; > } > /** > * getCode- > * > * Returns the code. > * > * @return int code > */ > public int getCode() { > return this.code; > } > /** > * setDisplayMessage- > * > * Sets the message. > * > * @param aDisplayMessage String to set > * > */ > public void setDisplayMessage(final String aDisplayMessage) { > this.displayMessage = aDisplayMessage.replace("\"", ""); > } > /** > * getDisplayMessage- > * > * Returns the message. > * > * @return String display message > */ > public String getDisplayMessage() { > return this.displayMessage; > } > /** > * setSeverity- > * > * Sets the severity. > * > * @param theSeverity String to set > * > */ > public void setSeverity(final String theSeverity) { > this.severity = theSeverity; > } > /** > * getSeverity- > * > * Returns the severity. > * > * @return String severity > */ > public String getSeverity() { > return this.severity; > } > /** > * getInformationCode- > * > * Returns the logicalName > * > * @return String information code > * > */ > public String getInformationCode() { > return this.informationCode; > } > /** > * getUserResolution- > * > * Returns the userResolution. > * > * @return String user resolution > * > */ > public String getUserResolution() { > return this.userResolution; > } > /** > * getUniqueID- > * > * Returns the unique id for the exception > * > * @return String Unique ID > */ > public String getUniqueID() { > return this.uniqueID; > } > /** > * setUniqueID- > * > * Sets the unique id for the exception > * > * @param uniqueID String to set > */ > public void setUniqueID(final String uniqueID) { > this.uniqueID = uniqueID; > } > /** > * getStack- > * > * Gets the stack trace of the exception that occurred > * > * @return String containing exception stack > */ > public String getStack() { > return stack; > } > /** > * setStack- > * Sets the stack trace of the exception that occurred > * > * @param stackTraceElements String representation of the stack to set > * > */ > public void setStack( > final String stack) { > this.stack = stack; > } > /** > * setStackTrace- > * Sets the stack trace of the exception that occurred > * > * @param stackTraceElements StackTraceElement array to set > * > */ > public void setStackTrace( > final StackTraceElement[] stack) { > if (stack != null) > { > StringBuilder builder = new StringBuilder(); > this.stack = ExceptionMessage.convert(builder, stack).toString(); > } > } > /** > * getExceptionCause- > * > * This method returns the original exception cause. A cause is another > * Throwable 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 String representation of the Throwable chained that was set > */ > public String getExceptionCause() { > return this.exceptionCause; > } > /** > * setExceptionCause- > * > * This method sets the original exception cause. A cause is another > * Throwable 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 String representation of Throwable chained exception to set > */ > public void setExceptionCause(final String exceptionCause) { > this.exceptionCause = exceptionCause; > } > /** > * setExceptionCausing- > * > * This method sets the original exception cause. A cause is another > * Throwable 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 Throwable exception to set > */ > public void setExceptionCausing(final Throwable exceptionCausing) { > this.exceptionCause = exceptionCausing.toString(); > } > /** > * getExceptionMessage- > * > * Returns the detail message string of this throwable. The detail message > * string of this Throwable instance (which may be null). > * > * @return String exceptionMessage > */ > public String getExceptionMessage() { > return this.exceptionMsg; > } > /** > * setExceptionMessage- > * > * Sets the detail message string of the Throwable that the exception > * message may use to display. this is optional and may not always be set. > * > * @param exceptionMessage String 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(); > } > /** > * convert- > * > * Converts the stack trace of an exception into StringBuilder from StackTraceElement. > * > * @param newStringBuilder StringBuilder buffer to which will be appended > * @param stack StackTraceElement array of elements to append to the stack > * > * @return StringBuilder 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