Details
-
Bug
-
Resolution: Won't Do
-
Major
-
jboss-ws4ee-4.0.0, jboss-ws4ee-4.0.1, jboss-ws4ee-4.0.2, jboss-ws4ee-4.0.3
-
None
Description
JBoss fails to support service specific exceptions that use inheritance (i.e. hava a different base class from java.lang.Exeption).
Fact 1:
According to the Java to WSDL/XML mapping defined in Section 5.5.5 of the JAX-RPC specification, Java exception inheritance is mapped using the XML Schema extension mechanism. To quote:
"Inheritance of Java exceptions is mapped using the derivation of xsd:complexType using the extension mechanism. This applies to the xsd:complexType used to
represent the single message part in the wsdl:message for the wsdl:fault."
Fact 2:
According to XML Schema : "When a complex type is derived by extension, its effective content model is the content model of the base type plus the content model specified in the type derivation. Furthermore, the two content models are treated as two children of a sequential group."
Fact 3:
As per the Basic Profile document, fault serialization must follow the rules of the document-literal binding.
To quote from Section 4.4.2:
"Because faults and headers do not contain parameters, soapbind:fault, soapbind:header and soapbind:headerfault assume, per WSDL 1.1, that the value of the style attribute is "document". R2204 requires that all wsdl:part elements with a style attribute whose value is "document" that are bound to soapbind:body be defined using the element attribute. This requirement does the same for soapbind:fault, soapbind:header and soapbind:headerfault elements."
Based on the above facts, when a compiant Application Server serializes a Service-specific exception, it must put the elements of a base class in front of those of a derived class to respect the XML schema semantics of complex type derivation by extension. JBoss fails to do that.
For instance suppose I have the following Java exception hierarchy and specify Exception2 in the throws clause of a business method of a service endpoint:
public class PrivateException extends java.lang.Exception {
public PrivateException() {
}
public PrivateException(java.lang.String description)
{ setDescription(description); } private java.lang.String description;
public java.lang.String getDescription()
public void setDescription(java.lang.String value)
{ this.description = value; }}
public class Exception2 extends PrivateException {
public Exception2() {
}
public Exception2(java.lang.String description, java.lang.String shortDescr)
{ super(description); setShortDescr(shortDescr); } private java.lang.String shortDescr;
public java.lang.String getShortDescr()
public void setShortDescr(java.lang.String value)
{ this.shortDescr = value; }}
The corresponding schema definition is:
<xsd:complexType name="Exception2">
<xsd:complexContent>
<xsd:extension base="tns1:PrivateException">
<xsd:all>
<xsd:element name="shortDescr" type="xsd:string"/>
</xsd:all>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="PrivateException">
<xsd:complexContent>
<xsd:extension base="tns:AlturaApplicationException">
<xsd:all>
<xsd:element name="description" type="xsd:string"/>
</xsd:all>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
When my business method throws an Exception2 exception, JBoss serializes the "shortDescr" element in front of "description".
The only way to force JBoss to use the correct order is to use a "special" java-xml-type-mapping entry in the JAX-RPC type mapping file that will list not only the properties of the derived class but also those of its base:
<java-xml-type-mapping>
<java-type>rootpackage.application.business.logic.Exception2</java-type>
<root-type-qname xmlns:typeNS="http://logic.business.application.rootpackage">typeNS:Exception2</root-type-qname>
<qname-scope>complexType</qname-scope>
<!-- The following variable mapping is not needed and shouldn't be specified, yet it's the only way to ensure that JBoss serializes Exception2 objects correctly. -->
<variable-mapping>
<java-variable-name>description</java-variable-name>
<xml-element-name>description</xml-element-name>
</variable-mapping>
<!-- This is the only variable mapping that is needed. -->
<variable-mapping>
<java-variable-name>shortDescr</java-variable-name>
<xml-element-name>shortDescr</xml-element-name>
</variable-mapping>
</java-xml-type-mapping>
<java-xml-type-mapping>
<java-type>rootpackage.application.business.logic.PrivateException</java-type>
<root-type-qname xmlns:typeNS="http://logic.business.application.rootpackage">typeNS:PrivateException</root-type-qname>
<qname-scope>complexType</qname-scope>
<variable-mapping>
<java-variable-name>description</java-variable-name>
<xml-element-name>description</xml-element-name>
</variable-mapping>
</java-xml-type-mapping>
This trick is not portable and is incompatible with the "Web Services for J2EE specification, Version 1.1" and other application servers (e.g. WebSphere).
Attachments
Issue Links
- is related to
-
JBWS-380 SOAPFault contains unwanted <message> element
- Closed