You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Brian Ewins <Br...@btinternet.com> on 2002/12/19 18:36:36 UTC

Problems with PROP_SEND_XSI

I am trying to get Axis to talk to a web service written by a third 
party which uses the 1999 Schema. I seem unable to convince Axis to use 
the 1999 schema, or to turn off sending the xsi:type info, which is 
causing a validation error at the other end.

This whole PROP_SEND_XSI/SEND_TYPE_ATTR issue seems to be almost 
entirely undocumented, but there are more mailing list posts about it 
than 'setSchemaVersion()' so I'm hoping someone might have had some success.

Trawling through the code, it appears to me that I should be doing:
_call.getMessageContext().setProperty(_call.SEND_TYPE_ATTR, Boolean.FALSE);

(in 'createCall' in a binding stub generated from WSDL[1])
However, I've also seen people try most of these variations:
// first one is in the 'TestXsiType' test case for Axis
// so should work!!
_call.getMessageContext().setProperty(Call.SEND_TYPE_ATTR, "false");
_call.setOption(Call.SEND_TYPE_ATTR,Boolean.FALSE);
_call.setProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
_call.setScopedProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
_call.setOption(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
_call.setProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
_call.setScopedProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
_call.getMessageContext().setProperty(AxisEngine.PROP_SEND_XSI, 
Boolean.FALSE);
_call.getService().getAxisEngine().setOption(AxisEngine.PROP_SEND_XSI, 
Boolean.FALSE);

(Also lots of examples with new Boolean(false). Which just creates new 
Boolean objects for no reason?) None of these are working for me. 
Digging further I found this code in SerializationContextImpl:
// Send the xmlType if indicated or if
// the actual xmlType is different than the
// prefered xmlType
if (shouldSendType ||
(xmlType != null &&
(!xmlType.equals(actualXMLType.value)))) {
      attributes = setTypeAttribute(attributes,
      actualXMLType.value);
}

Hmmm I think that going against the explicitly set value of 
'shouldSetType' deserves a log message...but anyway I think this is the 
crux of my problem. My generated code had :
_call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), new 
javax.xml.namespace.QName("http://www.w3.org/1999/XMLSchema", "string"), 
java.lang.String.class, javax.xml.rpc.ParameterMode.IN);

however the fragment from Axis above suggests I need to use this instead:
_call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), new 
javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), 
java.lang.String.class, javax.xml.rpc.ParameterMode.IN);

to prevent axis from writing the type I don't want to see in the call. 
Fine, I'll accept any level of insanity if the code works ;) However, 
this doesnt work either:

15273 [Thread-4] DEBUG org.apache.axis.client.Call  - Enter: 
Call::invoke(ns, meth, args)
15303 [Thread-4] DEBUG org.apache.axis.client.Call  - operation=name: 
    null
returnQName: null
returnType:  {http://www.w3.org/2001/XMLSchema}string
returnClass: class java.lang.String
elementQName:null
soapAction:  null
style:       rpc
numInParams: 1
method:null
  ParameterDesc[0]:
   name:       XMLRequest
   typeEntry:  null
   mode:       IN
   isReturn:   false
   typeQName:  {http://www.w3.org/2001/XMLSchema}string
   javaType:   class java.lang.String
[...snip...]
15453 [Thread-4] DEBUG org.apache.axis.client.Call  - <?xml 
version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSc
hema-instance">
  <soapenv:Body>
   <ns1:XMLListForms 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:ns1="/jetforms/soap/Server.xml">
    <XMLRequest xsi:type="xsd:string">[data snipped]</XMLRequest>
   </ns1:XMLListForms>
  </soapenv:Body>
</soapenv:Envelope>

(NB the operation name and method appear to be null above because axis 
doesnt set them, eg Call uses 'operationName' rather than set the name 
of 'operation'; this doesnt look like an error in my code)

Anyway, I'm off to run this under a debugger to see if there is some 
/other/ way the code can ignore me telling it not to send xsi:types. Has 
anyone got any idea how to get shot of the xsi:type? Or how to get 
setSchemaVersion to work?

-Baz


[1]the author of the other service is still using SDL to spec it. In 
previous releases of the service the WSDL I've written to match it has 
worked from axis because it didn't check my xsi:types. I know from 
checking network traces against another client that the code I'm sending 
is entirely correct apart from the xsi:type.




SchemaVersion is broken was Re: Problems with PROP_SEND_XSI

Posted by Brian Ewins <Br...@btinternet.com>.
A bunch of debugging later - I now know first of all that any attempt at 
trying to turn off XSI types on the MessageContext will never work:

_call.getMessageContext().setProperty(_call.SEND_TYPE_ATTR,Boolean.FALSE);
...
java.lang.Object _resp = _call.invoke(new java.lang.Object[] {XMLRequest});

because line 2104 of Call.java in the 1.0 release resets the properties 
of the MessageContext after you set them. I gave up that tack and I went 
back to getting setSchemaVersion() to work.

***It turns out it doesnt work at all.***

Here's code that gets close, again this would go in a WSDL2Java 
generated 'createCall':

org.apache.axis.MessageContext msgContext = _call.getMessageContext();	
// set soapconstants because of this comment in
// SerializationContextImpl.initialize:
// MAKE SURE soapConstants IS SET CORRECTLY FIRST!
msgContext.setSOAPConstants(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);

// we need to explicitly set the encoding style because otherwise
// MessageContext grabs it from the SoapConstants BEFORE
// SoapConstants is set!!	 
msgContext.setEncodingStyle(org.apache.axis.Constants.URI_SOAP11_ENC);

// ok now we can set the schema version
msgContext.setSchemaVersion(org.apache.axis.schema.SchemaVersion.SCHEMA_1999);

// that should have been enough, but all the registered simple types for
// the 1999 schema are WRONG - they are registered in wrong namespace.
QName xmlType=new QName("http://www.w3.org/1999/XMLSchema", "string");
_call.registerTypeMapping(String.class,
   new QName("http://www.w3.org/1999/XMLSchema", "string"),
   new SimpleSerializerFactory(String.class, xmlType),
   new SimpleDeserializerFactory(String.lass, xmlType));

This still produces the wrong message, viz:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
   <ns1:XMLListForms 
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:ns1="/jetforms/soap/Server.xml">
    <XMLRequest xsi:type="xsd:string" 
xmlns:xsd="http://www.w3.org/1999/XMLSchema">[data]</XMLRequest>
   </ns1:XMLListForms>
  </soapenv:Body>
</soapenv:Envelope>

Notice the envelope still uses the 2001 xsi namespace, but switches to 
1999 for xsd because of the extra type mapping. This xsi namespace is 
being set in SerializationContextImpl.setTypeAttribute to the hardcoded 
value Constants.URI_DEFAULT_SCHEMA_XSI when it should probably be be 
schemaVersion.getXsiUri(). So, theres no way to fix this without 
altering the code in Axis.

Theres a whole heap of bugs here, from encodingStyle being grabbed too 
early, to all the the basic 1999 types being registered in the wrong 
namespace, to the final disaster of a hardcoded namespace for the type 
attribute :( . Interop with 1999 schema services is basically shafted.

I'll have a go at the AxisEngine way of turning off XSI types but this 
is getting a bit silly - for services this simple I could have written 
the clients by hand (sigh), and I'll probably end up doing that now.

-Baz


Re: Problems with PROP_SEND_XSI

Posted by Brian Ewins <Br...@btinternet.com>.
I only sent the one example in the logs because thats the only thing 
that axis ever sends, no matter what I do!! But to be explicit:

 >> 15453 [Thread-4] DEBUG org.apache.axis.client.Call  - <?xml
 >> version="1.0" encoding="UTF-8"?>
 >> <soapenv:Envelope
 >> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 >> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 >> xmlns:xsi="http://www.w3.org/2001/XMLSc
 >> hema-instance">
 >>  <soapenv:Body>
 >>   <ns1:XMLListForms
 >> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
 >> xmlns:ns1="/jetforms/soap/Server.xml">
 >>    <XMLRequest xsi:type="xsd:string">[data snipped]</XMLRequest>
 >>   </ns1:XMLListForms>
 >>  </soapenv:Body>
 >> </soapenv:Envelope>

what is logged here is what is exactly what is being sent[1] with the 
unmodified code generated by WSDL2Java, from WSDL which defines 
XMLRequest as being {http://www.w3.org/1999/XMLSchema}string, and that 
1999 does make it into the generated code. This doesnt change with /any/ 
of the various attempts to turn off xsi:type, or with
_call.getMessageContext().setSchemaVersion(SchemaVersion.SCHEMA_1999);
(which to me looks like how I'm supposed to fix this problem. I havent 
spent so much time tracing through where that one gets checked.)

As for this being a spec violation - tell me about it. The service I'm 
talking to seems designed by someone who uses specs as a list of things 
/not/ to do. Every release of their software is worse than the last.

-Baz

[1] This isn't just something wrong with the logs. I'm also looking at 
the messages on the wire in capeclear's nettool.

Dennis Sosnoski wrote:
> Hi Brian,
> 
> I don't know about the schema issue. On the xsiTypes issue it'd be 
> useful if you could show what gets sent by Axis when you turn off 
> PROP_SEND_XSI to show what's causing the problem (without your patching 
> anything other than turning off the flag). Axis will still send types at 
> times even with PROP_SEND_XSI false, because they're required by the 
> SOAP spec. Think of it as controlling the sending of optional type 
> information...
> 
>  - Dennis
> 
> Dennis M. Sosnoski
> Enterprise Java, XML, and Web Services Support
> http://www.sosnoski.com
> Redmond, WA  425.885.7197
> 
> Brian Ewins wrote:
> 
>> I am trying to get Axis to talk to a web service written by a third 
>> party which uses the 1999 Schema. I seem unable to convince Axis to 
>> use the 1999 schema, or to turn off sending the xsi:type info, which 
>> is causing a validation error at the other end.
>>
>> This whole PROP_SEND_XSI/SEND_TYPE_ATTR issue seems to be almost 
>> entirely undocumented, but there are more mailing list posts about it 
>> than 'setSchemaVersion()' so I'm hoping someone might have had some 
>> success.
>>
>> Trawling through the code, it appears to me that I should be doing:
>> _call.getMessageContext().setProperty(_call.SEND_TYPE_ATTR, 
>> Boolean.FALSE);
>>
>> (in 'createCall' in a binding stub generated from WSDL[1])
>> However, I've also seen people try most of these variations:
>> // first one is in the 'TestXsiType' test case for Axis
>> // so should work!!
>> _call.getMessageContext().setProperty(Call.SEND_TYPE_ATTR, "false");
>> _call.setOption(Call.SEND_TYPE_ATTR,Boolean.FALSE);
>> _call.setProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
>> _call.setScopedProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
>> _call.setOption(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
>> _call.setProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
>> _call.setScopedProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
>> _call.getMessageContext().setProperty(AxisEngine.PROP_SEND_XSI, 
>> Boolean.FALSE);
>> _call.getService().getAxisEngine().setOption(AxisEngine.PROP_SEND_XSI, 
>> Boolean.FALSE);
>>
>> (Also lots of examples with new Boolean(false). Which just creates new 
>> Boolean objects for no reason?) None of these are working for me. 
>> Digging further I found this code in SerializationContextImpl:
>> // Send the xmlType if indicated or if
>> // the actual xmlType is different than the
>> // prefered xmlType
>> if (shouldSendType ||
>> (xmlType != null &&
>> (!xmlType.equals(actualXMLType.value)))) {
>>      attributes = setTypeAttribute(attributes,
>>      actualXMLType.value);
>> }
>>
>> Hmmm I think that going against the explicitly set value of 
>> 'shouldSetType' deserves a log message...but anyway I think this is 
>> the crux of my problem. My generated code had :
>> _call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), 
>> new javax.xml.namespace.QName("http://www.w3.org/1999/XMLSchema", 
>> "string"), java.lang.String.class, javax.xml.rpc.ParameterMode.IN);
>>
>> however the fragment from Axis above suggests I need to use this instead:
>> _call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), 
>> new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", 
>> "string"), java.lang.String.class, javax.xml.rpc.ParameterMode.IN);
>>
>> to prevent axis from writing the type I don't want to see in the call. 
>> Fine, I'll accept any level of insanity if the code works ;) However, 
>> this doesnt work either:
>>
>> 15273 [Thread-4] DEBUG org.apache.axis.client.Call  - Enter: 
>> Call::invoke(ns, meth, args)
>> 15303 [Thread-4] DEBUG org.apache.axis.client.Call  - operation=name: 
>>    null
>> returnQName: null
>> returnType:  {http://www.w3.org/2001/XMLSchema}string
>> returnClass: class java.lang.String
>> elementQName:null
>> soapAction:  null
>> style:       rpc
>> numInParams: 1
>> method:null
>>  ParameterDesc[0]:
>>   name:       XMLRequest
>>   typeEntry:  null
>>   mode:       IN
>>   isReturn:   false
>>   typeQName:  {http://www.w3.org/2001/XMLSchema}string
>>   javaType:   class java.lang.String
>> [...snip...]
>> 15453 [Thread-4] DEBUG org.apache.axis.client.Call  - <?xml 
>> version="1.0" encoding="UTF-8"?>
>> <soapenv:Envelope 
>> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
>> xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
>> xmlns:xsi="http://www.w3.org/2001/XMLSc
>> hema-instance">
>>  <soapenv:Body>
>>   <ns1:XMLListForms 
>> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
>> xmlns:ns1="/jetforms/soap/Server.xml">
>>    <XMLRequest xsi:type="xsd:string">[data snipped]</XMLRequest>
>>   </ns1:XMLListForms>
>>  </soapenv:Body>
>> </soapenv:Envelope>
>>
>> (NB the operation name and method appear to be null above because axis 
>> doesnt set them, eg Call uses 'operationName' rather than set the name 
>> of 'operation'; this doesnt look like an error in my code)
>>
>> Anyway, I'm off to run this under a debugger to see if there is some 
>> /other/ way the code can ignore me telling it not to send xsi:types. 
>> Has anyone got any idea how to get shot of the xsi:type? Or how to get 
>> setSchemaVersion to work?
>>
>> -Baz
>>
>>
>> [1]the author of the other service is still using SDL to spec it. In 
>> previous releases of the service the WSDL I've written to match it has 
>> worked from axis because it didn't check my xsi:types. I know from 
>> checking network traces against another client that the code I'm 
>> sending is entirely correct apart from the xsi:type.
>>
>>
>>
> 
> 


Re: Problems with PROP_SEND_XSI

Posted by Dennis Sosnoski <dm...@sosnoski.com>.
Hi Brian,

I don't know about the schema issue. On the xsiTypes issue it'd be 
useful if you could show what gets sent by Axis when you turn off 
PROP_SEND_XSI to show what's causing the problem (without your patching 
anything other than turning off the flag). Axis will still send types at 
times even with PROP_SEND_XSI false, because they're required by the 
SOAP spec. Think of it as controlling the sending of optional type 
information...

  - Dennis

Dennis M. Sosnoski
Enterprise Java, XML, and Web Services Support
http://www.sosnoski.com
Redmond, WA  425.885.7197

Brian Ewins wrote:

> I am trying to get Axis to talk to a web service written by a third 
> party which uses the 1999 Schema. I seem unable to convince Axis to 
> use the 1999 schema, or to turn off sending the xsi:type info, which 
> is causing a validation error at the other end.
>
> This whole PROP_SEND_XSI/SEND_TYPE_ATTR issue seems to be almost 
> entirely undocumented, but there are more mailing list posts about it 
> than 'setSchemaVersion()' so I'm hoping someone might have had some 
> success.
>
> Trawling through the code, it appears to me that I should be doing:
> _call.getMessageContext().setProperty(_call.SEND_TYPE_ATTR, 
> Boolean.FALSE);
>
> (in 'createCall' in a binding stub generated from WSDL[1])
> However, I've also seen people try most of these variations:
> // first one is in the 'TestXsiType' test case for Axis
> // so should work!!
> _call.getMessageContext().setProperty(Call.SEND_TYPE_ATTR, "false");
> _call.setOption(Call.SEND_TYPE_ATTR,Boolean.FALSE);
> _call.setProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
> _call.setScopedProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE);
> _call.setOption(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
> _call.setProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
> _call.setScopedProperty(AxisEngine.PROP_SEND_XSI,Boolean.FALSE);
> _call.getMessageContext().setProperty(AxisEngine.PROP_SEND_XSI, 
> Boolean.FALSE);
> _call.getService().getAxisEngine().setOption(AxisEngine.PROP_SEND_XSI, 
> Boolean.FALSE);
>
> (Also lots of examples with new Boolean(false). Which just creates new 
> Boolean objects for no reason?) None of these are working for me. 
> Digging further I found this code in SerializationContextImpl:
> // Send the xmlType if indicated or if
> // the actual xmlType is different than the
> // prefered xmlType
> if (shouldSendType ||
> (xmlType != null &&
> (!xmlType.equals(actualXMLType.value)))) {
>      attributes = setTypeAttribute(attributes,
>      actualXMLType.value);
> }
>
> Hmmm I think that going against the explicitly set value of 
> 'shouldSetType' deserves a log message...but anyway I think this is 
> the crux of my problem. My generated code had :
> _call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), 
> new javax.xml.namespace.QName("http://www.w3.org/1999/XMLSchema", 
> "string"), java.lang.String.class, javax.xml.rpc.ParameterMode.IN);
>
> however the fragment from Axis above suggests I need to use this instead:
> _call.addParameter(new javax.xml.namespace.QName("", "XMLRequest"), 
> new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", 
> "string"), java.lang.String.class, javax.xml.rpc.ParameterMode.IN);
>
> to prevent axis from writing the type I don't want to see in the call. 
> Fine, I'll accept any level of insanity if the code works ;) However, 
> this doesnt work either:
>
> 15273 [Thread-4] DEBUG org.apache.axis.client.Call  - Enter: 
> Call::invoke(ns, meth, args)
> 15303 [Thread-4] DEBUG org.apache.axis.client.Call  - operation=name: 
>    null
> returnQName: null
> returnType:  {http://www.w3.org/2001/XMLSchema}string
> returnClass: class java.lang.String
> elementQName:null
> soapAction:  null
> style:       rpc
> numInParams: 1
> method:null
>  ParameterDesc[0]:
>   name:       XMLRequest
>   typeEntry:  null
>   mode:       IN
>   isReturn:   false
>   typeQName:  {http://www.w3.org/2001/XMLSchema}string
>   javaType:   class java.lang.String
> [...snip...]
> 15453 [Thread-4] DEBUG org.apache.axis.client.Call  - <?xml 
> version="1.0" encoding="UTF-8"?>
> <soapenv:Envelope 
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
> xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
> xmlns:xsi="http://www.w3.org/2001/XMLSc
> hema-instance">
>  <soapenv:Body>
>   <ns1:XMLListForms 
> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
> xmlns:ns1="/jetforms/soap/Server.xml">
>    <XMLRequest xsi:type="xsd:string">[data snipped]</XMLRequest>
>   </ns1:XMLListForms>
>  </soapenv:Body>
> </soapenv:Envelope>
>
> (NB the operation name and method appear to be null above because axis 
> doesnt set them, eg Call uses 'operationName' rather than set the name 
> of 'operation'; this doesnt look like an error in my code)
>
> Anyway, I'm off to run this under a debugger to see if there is some 
> /other/ way the code can ignore me telling it not to send xsi:types. 
> Has anyone got any idea how to get shot of the xsi:type? Or how to get 
> setSchemaVersion to work?
>
> -Baz
>
>
> [1]the author of the other service is still using SDL to spec it. In 
> previous releases of the service the WSDL I've written to match it has 
> worked from axis because it didn't check my xsi:types. I know from 
> checking network traces against another client that the code I'm 
> sending is entirely correct apart from the xsi:type.
>
>
>