Um, but that contradicts the section of the User's guide I quoted below.
Is the User's guide wrong? That would be unfortunate, because I've
wasted a couple of days on the assumption that it's correct.
What I'm trying to do is this: We've got a service, which is basically a
POJO (i.e. no axis-isms or web service-isms) that we're deploying using
wsdd (a minimal wsdd) without generating WSDL or any of that. On the
client side, I'm creating a dynamic proxy which uses the sample code
example to parse the axis-generated WSDL (the one you get from
http://foo.com/axis/service/myService?wsdl) and figure out how to call
the method and get everything back. Everything works just fine except
for exceptions.
I'd rather not extend AxisFault for a couple of reasons:
1) My service right now has no knowledge that it's running within Axis,
or even that it's a web service. I'd like to keep it that way
2) My client may be accessing web services which aren't in my control. I
can't assume that they're going to throw exceptions which inherit from
AxisFault.
3) There is no number 3. ;-)
It doesn't make much sense to me that axis would have this wonderful
mechanism whereby we can install a fairly arbitrary Java class and turn
it magically into a web service...unless you throw exceptions, in which
case all bets are off. Of course, I've been wrong before.
Here's the wsdd file:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="ClaimsData" provider="java:RPC">
<parameter name="className"
value="com.foo.ecommerce.dataservice.ClaimDataService"/>
<parameter name="allowedMethods" value="*"/>
<beanMapping qname="myNS:Claim" xmlns:myNS="urn:ClaimsData"
languageSpecificType="java:com.foo.ecommerce.beans.Claim"/>
</service>
</deployment>
Here's the generated WSDL:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" xmlns:intf="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="urn:ClaimsData" xmlns:tns2="http://beans.ecommerce.foo.com"
xmlns:tns3="http://dao.ecommerce.foo.com" xmlns:tns4="http://hib.ecommerce.foo.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.3
Built on Oct 05, 2005 (05:23:37 EDT)-->
<wsdl:types>
<schema targetNamespace="urn:ClaimsData"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://hib.ecommerce.foo.com"/>
<import
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"/>
<import namespace="http://dao.ecommerce.foo.com"/>
<import namespace="http://beans.ecommerce.foo.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="Claim">
<sequence>
<element name="amount" type="xsd:double"/>
<element name="claimDate" nillable="true" type="xsd:dateTime"/>
<element name="claimDesc" nillable="true" type="xsd:string"/>
<element name="claimID" type="xsd:long"/>
<element name="claimNumber" nillable="true" type="xsd:string"/>
<element name="claimStatus" nillable="true" type="xsd:string"/>
<element name="claimStatusName" nillable="true" type="xsd:string"/>
<element name="formattedDate" nillable="true" type="xsd:string"/>
<element name="policy" nillable="true" type="xsd:anyType"/>
<element name="policyHolder" nillable="true" type="xsd:string"/>
<element name="provider" nillable="true" type="xsd:anyType"/>
</sequence>
</complexType>
</schema>
<schema targetNamespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://hib.ecommerce.foo.com"/>
<import namespace="http://dao.ecommerce.foo.com"/>
<import namespace="urn:ClaimsData"/>
<import namespace="http://beans.ecommerce.foo.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="ArrayOf_tns1_Claim">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:Claim[]"/>
</restriction>
</complexContent>
</complexType>
</schema>
<schema targetNamespace="http://beans.ecommerce.foo.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://hib.ecommerce.foo.com"/>
<import
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"/>
<import namespace="http://dao.ecommerce.foo.com"/>
<import namespace="urn:ClaimsData"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="InvalidDateException">
<sequence/>
</complexType>
</schema>
<schema targetNamespace="http://dao.ecommerce.foo.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://hib.ecommerce.foo.com"/>
<import
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"/>
<import namespace="urn:ClaimsData"/>
<import namespace="http://beans.ecommerce.foo.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="ClaimDataAccessException">
<sequence/>
</complexType>
</schema>
<schema targetNamespace="http://hib.ecommerce.foo.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<import
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"/>
<import namespace="http://dao.ecommerce.foo.com"/>
<import namespace="urn:ClaimsData"/>
<import namespace="http://beans.ecommerce.foo.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="HibernateException">
<sequence/>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getClaimsByDateRequest">
<wsdl:part name="beginDate" type="soapenc:string"/>
<wsdl:part name="endDate" type="soapenc:string"/>
</wsdl:message>
<wsdl:message name="getClaimsByProviderNameResponse">
<wsdl:part name="getClaimsByProviderNameReturn"
type="impl:ArrayOf_tns1_Claim"/>
</wsdl:message>
<wsdl:message name="ClaimDataAccessException">
<wsdl:part name="fault" type="tns3:ClaimDataAccessException"/>
</wsdl:message>
<wsdl:message name="getClaimsByProviderRequest">
<wsdl:part name="providerID" type="soapenc:string"/>
</wsdl:message>
<wsdl:message name="getClaimsByProviderNameRequest">
<wsdl:part name="providerID" type="soapenc:string"/>
<wsdl:part name="name" type="soapenc:string"/>
</wsdl:message>
<wsdl:message name="addClaimRequest">
<wsdl:part name="claim" type="tns1:Claim"/>
</wsdl:message>
<wsdl:message name="addClaimResponse">
</wsdl:message>
<wsdl:message name="getClaimsByProviderDateRequest">
<wsdl:part name="providerID" type="soapenc:string"/>
<wsdl:part name="beginDate" type="soapenc:string"/>
<wsdl:part name="endDate" type="soapenc:string"/>
</wsdl:message>
<wsdl:message name="getClaimsByProviderResponse">
<wsdl:part name="getClaimsByProviderReturn"
type="impl:ArrayOf_tns1_Claim"/>
</wsdl:message>
<wsdl:message name="getClaimsByProviderDateResponse">
<wsdl:part name="getClaimsByProviderDateReturn"
type="impl:ArrayOf_tns1_Claim"/>
</wsdl:message>
<wsdl:message name="getClaimsByDateResponse">
<wsdl:part name="getClaimsByDateReturn" type="impl:ArrayOf_tns1_Claim"/>
</wsdl:message>
<wsdl:message name="InvalidDateException">
<wsdl:part name="fault" type="tns2:InvalidDateException"/>
</wsdl:message>
<wsdl:message name="HibernateException">
<wsdl:part name="fault" type="tns4:HibernateException"/>
</wsdl:message>
<wsdl:portType name="ClaimDataService">
<wsdl:operation name="getClaimsByDate" parameterOrder="beginDate endDate">
<wsdl:input message="impl:getClaimsByDateRequest"
name="getClaimsByDateRequest"/>
<wsdl:output message="impl:getClaimsByDateResponse"
name="getClaimsByDateResponse"/>
<wsdl:fault message="impl:ClaimDataAccessException"
name="ClaimDataAccessException"/>
<wsdl:fault message="impl:InvalidDateException"
name="InvalidDateException"/>
</wsdl:operation>
<wsdl:operation name="getClaimsByProvider" parameterOrder="providerID">
<wsdl:input message="impl:getClaimsByProviderRequest"
name="getClaimsByProviderRequest"/>
<wsdl:output message="impl:getClaimsByProviderResponse"
name="getClaimsByProviderResponse"/>
<wsdl:fault message="impl:ClaimDataAccessException"
name="ClaimDataAccessException"/>
</wsdl:operation>
<wsdl:operation name="getClaimsByProviderName" parameterOrder="providerID
name">
<wsdl:input message="impl:getClaimsByProviderNameRequest"
name="getClaimsByProviderNameRequest"/>
<wsdl:output message="impl:getClaimsByProviderNameResponse"
name="getClaimsByProviderNameResponse"/>
<wsdl:fault message="impl:ClaimDataAccessException"
name="ClaimDataAccessException"/>
</wsdl:operation>
<wsdl:operation name="getClaimsByProviderDate" parameterOrder="providerID
beginDate endDate">
<wsdl:input message="impl:getClaimsByProviderDateRequest"
name="getClaimsByProviderDateRequest"/>
<wsdl:output message="impl:getClaimsByProviderDateResponse"
name="getClaimsByProviderDateResponse"/>
<wsdl:fault message="impl:ClaimDataAccessException"
name="ClaimDataAccessException"/>
<wsdl:fault message="impl:InvalidDateException"
name="InvalidDateException"/>
</wsdl:operation>
<wsdl:operation name="addClaim" parameterOrder="claim">
<wsdl:input message="impl:addClaimRequest" name="addClaimRequest"/>
<wsdl:output message="impl:addClaimResponse" name="addClaimResponse"/>
<wsdl:fault message="impl:ClaimDataAccessException"
name="ClaimDataAccessException"/>
<wsdl:fault message="impl:HibernateException"
name="HibernateException"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ClaimsDataSoapBinding" type="impl:ClaimDataService">
<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getClaimsByDate">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getClaimsByDateRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dataservice.ecommerce.foo.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getClaimsByDateResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" use="encoded"/>
</wsdl:output>
<wsdl:fault name="ClaimDataAccessException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="ClaimDataAccessException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
<wsdl:fault name="InvalidDateException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="InvalidDateException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="getClaimsByProvider">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getClaimsByProviderRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dataservice.ecommerce.foo.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getClaimsByProviderResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" use="encoded"/>
</wsdl:output>
<wsdl:fault name="ClaimDataAccessException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="ClaimDataAccessException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="getClaimsByProviderName">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getClaimsByProviderNameRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dataservice.ecommerce.foo.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getClaimsByProviderNameResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" use="encoded"/>
</wsdl:output>
<wsdl:fault name="ClaimDataAccessException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="ClaimDataAccessException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="getClaimsByProviderDate">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getClaimsByProviderDateRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dataservice.ecommerce.foo.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="getClaimsByProviderDateResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" use="encoded"/>
</wsdl:output>
<wsdl:fault name="ClaimDataAccessException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="ClaimDataAccessException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
<wsdl:fault name="InvalidDateException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="InvalidDateException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="addClaim">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="addClaimRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://dataservice.ecommerce.foo.com" use="encoded"/>
</wsdl:input>
<wsdl:output name="addClaimResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData" use="encoded"/>
</wsdl:output>
<wsdl:fault name="ClaimDataAccessException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="ClaimDataAccessException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
<wsdl:fault name="HibernateException">
<wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
name="HibernateException" namespace="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"
use="encoded"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ClaimDataServiceService">
<wsdl:port binding="impl:ClaimsDataSoapBinding" name="ClaimsData">
<wsdlsoap:address
location="http://staportal01.stratarc.net:8080/axis/services/ClaimsData"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Thanks.
-Jack
Dies Koper wrote:
Hello Jack,
As Jarmo pointed out, all client-side (generated) exceptions extend
AxisFault. Are you not using the generated exceptions?
The WSDL defines the interface, including the faults. Either you let
Axis do the mapping to Java using its own generated classes, or you do
not. I don't think Axis could do its job without them.
There is no need to catch an AxisFault first and then doing an
instanceof. Jarmo must have written that code before he had his coffee ;)
Your client does not (and should not) need to know that AxisFault is
being used internally.
Could you show us the WSDL that defines your fault (complexType +
<message>, etc.), the SOAP response containing the fault, and the code
you use to catch the exception?
Regards,
Dies
Jack Lund wrote:
Yeah, I can see that that would be easier. Unfortunately, I have no
control over the exceptions being thrown - I just need the
client-side to be able to catch them *as* the exceptions that are
originally thrown. I also am doing dynamic proxying rather than
stubs/skeletons, so it makes it that more complicated.
From the debugging I've been able to do, it looks like the fault
coming across contains the fully-qualified package name of the
exception class, but for some reason on the client side it's not
creating the exception. Since this is an area where there's
practically no documentation, I'm finding myself pretty much randomly
trying different things and seeing if they work.
The user's guide is really vague about this subject:
"If a method is marked as throwing an Exception that is not an
instance or a subclass of java.rmi.RemoteException, then things are
subtly different. The exception is no longer a SOAP Fault, but
described as a wsdl:fault in the WSDL of the method. According to the
JAX-RPC specification, your subclass of Exception must have accessor
methods to access all the fields in the object to be marshalled /and/
a constructor that takes as parameters all the same fields (i.e,
arguments of the same name and type). This is a kind of immutable
variant of a normal JavaBean
<http://java.sun.com/products/javabeans>. The fields in the object
must be of the datatypes that can be reliably mapped into WSDL.
If your exception meets this specification, then the WSDL describing
the method will describe the exception too, enabling callers to
create stub implementations of the exception, regardless of platform."
I was kind of hoping someone else out there would have had some
experience with getting this to work.
-Jack
Jarmo Doc wrote:
I have an Axis client stub which was generated from WSDL. *All* of
the client-side user-defined exceptions extend
org.apache.axis.AxisFault.
The equivalent exceptions at the server also extend
org.apache.axis.AxisFault, rather than Exception.
This is a decidedly dodgy area, imo, especially when it comes to
interop with non-Axis clients.
From: Jack Lund <[EMAIL PROTECTED]>
Reply-To: [email protected]
To: [email protected]
Subject: RE: Problems getting user exceptions to work
Date: Wed, 29 Mar 2006 14:51:47 -0600
Nope, didn't work. Wouldn't think it would - AxisFault isn't a
subclass of InvalidDateException.
-Jack
Jarmo Doc wrote:
Try doing this:
catch (AxisFault ex)
{
if (ex instanceof InvalidDateException)
{
InvalidDateException myex = (InvalidDateException)ex;
// deal with myex here
}
// deal with others here
}
From: Jack Lund <[EMAIL PROTECTED]>
Reply-To: [email protected]
To: [email protected]
Subject: Problems getting user exceptions to work
Date: Wed, 29 Mar 2006 12:21:33 -0600
Hi. I'm using axis 1.2.1, and I'm trying to get the exceptions
sent by my service thrown to the client. For instance, my service
can throw an "InvalidDateException" exception, which is a
subclass of java.lang.Exception, and I want the client code to
get that exception. What little is said on the axis website about
this implies that it should "just work", but it doesn't seem to -
what I get on the other side is an AxisFault with the message
string from my exception embedded inside.
Is there something special I have to do, on either side, to get
this to work?
Thanks.
-Jack