Yowch!  I don't envy you your little debugging chore you had to go through!

1)  Sounds reasonable to me.
2)  I'm not sure I understand.
3)  I don't know how you'd do this without some protocol.  SOAPAction is
deprecated and there is not protocol for passing meta-info in the
soap:header.
4)  I gave the clash test a fairly good going over last week, so I THINK
it's a correct test.  Whether it's a good test is another question.  I
tried to create a WSDL with as many things with the same name as I could.
I tried covering all bases in one test.  Perhaps this should be done with
multiple WSDL files rather than one.  We can discuss it tomorrow.

I'm still not sure I understand the problem with the clash test.  The
testcase is calling "void sharedName(int)".  That method DOES exist on all
the generated files:  the interface, the skeleton, the impl.  It is
overloaded:  "void sharedName(int)", "int sharedName()", "void
sharedName(boolean)".  "<sharedName>0</sharedName>" shouldn't be ambiguous
(or is 0 a legal boolean value?).  What exactly is the error you're seeing?

Russell Butek
[EMAIL PROTECTED]


Glen Daniels <[EMAIL PROTECTED]> on 02/19/2002 05:16:25 PM

Please respond to [EMAIL PROTECTED]

To:   "'Axis-Dev (E-mail)'" <[EMAIL PROTECTED]>
cc:
Subject:  Clash test




Hi guys:

I'm in the midst of revamping some stuff, during which I did some surgery
on the way RPCProvider dispatches to target methods.  In particular, I
added a clause to save some time which ignores overloaded methods with
FEWER parameters than those we have from the XML deserialization.  This lit
up a serious bug that had been present in the code - namely the fact that
if there were no arguments in a given method, that one would get called
regardless of the argument list we were currently working with from the
XML.  In other words if you had:

 public int method() { return 5; }
 public void method(int value) { // do something }

And received XML with a single int param, it's just as likely you'd
dispatch to the first method as the second.

Turns out this bug, which has been sitting there a while, it seems, is the
reason that the wsdl "clash" test was working.  Once it was fixed, the
problems with the clash test became apparent.

In particular, test #5 in the SharedName_ServiceTestCase calls what it
thinks is the method that looks like "void sharedName(int)".  It sends XML
that contains a parameter that has no xsi:type on it (since it's literal),
with an element name of <sharedName>, i.e. <sharedName>0</sharedName>.  So
the runtime gets this, and since there are multiple "sharedName" methods,
it can't figure out the types from introspection via determineDefaultParams
() (in org.apache.axis.message.RPCHandler).  So it looks for a type
attribute - no luck.  Then it says "hey, does the element QName happen to
match a type I know about?" and lo and behold it does - only this isn't an
int, it's a "SharedNameType".  So we merrily attempt to deserialize one of
those, even though the XML isn't quite right for that (NOTE: we should
probably be able to enforce throwing faults for missing bean elements).
OK, so now we have our SharedNameType in hand, and get to RPCProvider to
figure out what method to call.  Well!
, because of the earlier bug I mentioned, we find the method that looks
like "int sharedName()", and since it has no params we just call it and
happily return.

That's what WAS happening.  Now the test breaks in my sandbox because we're
NOT calling the wrong backend method.

So how do we deal with this?  It's a little hard to pinpoint the exact
problem(s), so let's tease it apart:

1) When lacking an xsi:type attribute, we don't know how to deserialize a
given piece of XML if there are multiple potential types.  Right now
there's an assumption that deserialization is done when we get to the
RPCProvider, and we just try JavaUtils.convert() to coerce whatever we have
into whatever we might want.  I think the right solution to this might be
to keep track of the fact that there are overloaded methods during
deserialization.  Pick a random method to use as "starter" metadata, and if
one of the deserializations fails, we should back up, click the method
counter forward, and try deserializing the XML again as the next type.

2) We should remove the "use the element QName as the type" code, I think
it might be bogus except for particular elements like <SOAP-ENC:int>.  It's
not a generally good thing.

3) We need to be able to differentiate between overloaded methods where you
can't dispatch based on the XML (i.e. "void method(int)" and "void
method(String)" where there's a single <arg>5</arg>).  Most other toolkits
seem to do this with SOAPAction, which we could do also.  We could also
have a SOAP header based solution.

4) The clash test should be given a thorough once-over.  .NET's wsdl tool
chokes on it, and I'm not convinced it's really good WSDL testing what we
want to test.

I have to go for the evening, but I'll take a look at this again tomorrow.
Russell, if you can spare some time I would really appreciate some help
going over the test to figure out what its doing right and wrong, because
I'd like to check my changes in at some point during the day tomorrow.

Comments/opinions welcome.

Thanks,
--Glen


Reply via email to