axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfle...@gmail.com
Subject Axis2 WSDL2Java ClientStub - Exceptions with same Qname - please help!
Date Mon, 28 May 2012 09:00:16 GMT
Hi all

I am new to Axis2. I am really hoping someone can help - as I have worked
around a few issues with the WSDL I have been given, but have no idea how
to work around this one.

I have generated a client stub to call a 3rd party web service using
Wsdl2Java (we are using an older Axis2 - 1.5.3).  The provided WSDL (and
XSDs imported into it) includes a number of faults which are generated and
returned by the stub as exceptions.  However the exceptions are not being
mapped properly as a result of the same name for exceptions in different
web service operations being used in the WSDL.  So this results in the
following happening in the stub:

* A number of Exceptions seem to have the same Qname.
* Only one Exception matching the QName is in the exception mapping tables.
 When the mapping table is built, entries with the same Qname overwrite
each other (as it is the key).
* However, the full exception name is different for each operation in the
service.
* When an operation's method is called in the stub that results in an
exception, a match for the exception is found in the mapping table, but it
may be the exception for another operation (as it was just the last one
with that Qname written).  As only that operation's exceptions are set up
in the method, the exception from the mapping table doesn't match any
exceptions for this operation.
* Therefore, the exception is effectively not found, and a more generic
java.rmi.RemoteException is thrown.

That was a bit confusing :P so an example:

The following is an excerpt from the populateFaults method generated in the
stub.  There is a RegistrationAccessFaultDetail fault for both the
DischargeRegistraton and ResetRegistration operations of the web service.

private void populateFaults(){

  faultExceptionNameMap.put( new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationService_DischargeRegistration_RegistrationAccessFaultDetailFault_FaultMessage");
  faultExceptionClassNameMap.put(new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationService_DischargeRegistration_RegistrationAccessFaultDetailFault_FaultMessage");
  faultMessageMap.put( new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationSoap12Stub$RegistrationAccessFaultDetailE");

  faultExceptionNameMap.put( new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationService_ResetRegistration_RegistrationAccessFaultDetailFault_FaultMessage");
  faultExceptionClassNameMap.put(new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationService_ResetRegistration_RegistrationAccessFaultDetailFault_FaultMessage");
  faultMessageMap.put( new javax.xml.namespace.QName("
http://schemas.xxx.xxx.xxx/faults
","RegistrationAccessFaultDetail"),"xxx.xxx.xxx.RegistrationSoap12Stub$RegistrationAccessFaultDetailE");
  .......

In the exception handler for the DischargeRegistration method we have:
...
 }catch(org.apache.axis2.AxisFault f){
  org.apache.axiom.om.OMElement faultElt = f.getDetail();
  if (faultElt!=null){
    if (faultExceptionNameMap.containsKey(faultElt.getQName())){
      //make the fault by reflection
      try{
        java.lang.String exceptionClassName =
(java.lang.String)faultExceptionClassNameMap.get(faultElt.getQName());
        java.lang.Class exceptionClass =
java.lang.Class.forName(exceptionClassName);
        java.lang.Exception ex = (java.lang.Exception)
exceptionClass.newInstance();
        //message class
        java.lang.String messageClassName =
(java.lang.String)faultMessageMap.get(faultElt.getQName());
        java.lang.Class messageClass =
java.lang.Class.forName(messageClassName);
        java.lang.Object messageObject = fromOM(faultElt,messageClass,null);
        java.lang.reflect.Method m =
exceptionClass.getMethod("setFaultMessage", new
java.lang.Class[]{messageClass});
        m.invoke(ex,new java.lang.Object[]{messageObject});

          if (ex instanceof
xxx.xxx.xxx.RegistrationService_DischargeRegistration_RegistrationAccessFaultDetailFault_FaultMessage){
            throw
(xxx.xxx.xxx.RegistrationService_DischargeRegistration_RegistrationAccessFaultDetailFault_FaultMessage)ex;
          }
          ....

          throw new java.rmi.RemoteException(ex.getMessage(), ex);

However, the exception for ResetRegistration was last added to the mapping
table, overwriting the fault for DischargeRegistration, and therefore the
instanceof check fails, and a RemoteException is thrown.

I have no control over the web service as it is from a third party, though
I could modify the WSDL if I needed to.

Has anyone encountered this?  Is there a way for Axis2 to handle this
situation?

Thanks heaps
Matt

Mime
View raw message