axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Anne Thomas Manes <atma...@gmail.com>
Subject Re: Can't invoke method with multiple arguments
Date Fri, 11 Feb 2005 00:01:16 GMT
Here's a reprise of a previous posting I made about WSDD styles:

One thing that causes a lot of confusion for Axis users is the
overloaded use of the term "style". This term refers to both the
message encoding style and the programming style. It's important to
distinguish these terms.

You specify the message encoding style using the WSDL "style" and
"use" attributes. You specify the programming style in the WSDD
"style" attribute.

There are three types of message encoding styles:
- rpc/encoded
- rpc/literal
- doc/literal

Note that there is no such thing as doc/encoded. Note also that
"wrapped" is a programming convention, not a message encoding style.

There are fundamentally two types of programming styles, as defined by
the JCP APIs for SOAP:
- JAX-RPC (method invocation, which correspond to Axis RPC, WRAPPED,
and DOCUMENT styles)
- JAXM (messaging, which correspond to Axis MESSAGE style)

Both of these APIs build on a common low-level API (SAAJ).

The difference between JAX-RPC and JAXM is equivalent to the
difference between RMI and JMS. With JAX-RPC, the runtime engine
automatically marshals the message contents for the application. With
JAXM, the application is responsible for constructing the message.

In other words, use JAX-RPC when your application wants to work with
Java objects; and use JAXM when your application wants to work with
XML.

Nearly all SOAP toolkits support both a method invocation and a
messaging interface. Nearly all Java-based SOAP toolkits support
JAX-RPC. About half the Java-based toolkits support JAXM -- the others
use a proprietary API. (Note that JAXM is not a requirement for J2EE
1.4.)

Axis RPC, WRAPPED, and DOCUMENT styles all implement JAX-RPC. Axis
MESSAGE style is proprietary messaging API. It does not implement
JAXM, but it is equivalent.

The names of these programming styles are proprietary to Axis -- none
of the WSF specs define any programming styles -- it's outside the
scope of SOAP or WSDL.

The Axis WSDD programming styles correspond to the WSDL encoding
styles as follows:

WSDD  ========>   WSDL
------------------------------------------------------------
RPC   =========>    rpc/encoded
WRAPPED   ====>    doc/literal using wrapped convention
DOCUMENT   ===>    doc/literal unwrapped
MESSAGE   ====>    doc/literal unwrapped

Note that Axis does not have a WSDD style that corresponds to
RPC/Literal. If you want to generate an RPC/Literal service (not
recommended), you need to specify style="RPC" and use="literal".

I disagree with your characterization of "message" style being "pure"
doc/lit. It is more "pure" XML, but it puts the onus on the developer
to make sure that the message format is correct. It's typically a much
better practice to let Axis generate your messages for you based on
the WSDL/schema definition.

Axis will let you plug an array of elements into a single SOAP body,
but it's going to produce errors. Likewise, if you define a
document/literal WSDL with multiple message parts, Axis will generate
a SOAP body with multiple child elements. And that, too, will generate
errors.

- Anne


On Thu, 10 Feb 2005 13:51:40 -0800, Linus Kamb
<linus@iris.washington.edu> wrote:
> I confess to being perpetually befuddled by the seeming inconsistencies
> between axis wsdd "style" terminology versus web-service / SOAP
> "style".
> 
> So how does the below requirement fit with the axis "Message style"
> service (which I thought of as some sort of "pure" doc/lit) which
> allows the following service method signatures (from axis user guide)?
> 
> public Element [] method(Element [] bodies);
> public SOAPBodyElement [] method (SOAPBodyElement [] bodies);
> public Document method(Document body);
> public void method(SOAPEnvelope req, SOAPEnvelope resp);
> 
> That seems to say to me that document/literal can have several Elements
> in the body.
> 
> I implemented a web service that accepted several Element objects.  It
> worked fine, except that I had to go through the whole call.invoke()
> mumbo-jumbo on the client side.
> 
> Thanks,
> Linus
> 
> On Feb 10, 2005, at 12:36 PM, Anne Thomas Manes wrote:
> 
> > This is not a bug -- this is a requirement of SOAP. The child element
> > of the SOAP body indicates to the SOAP processor how to handle the
> > request. This child element must provide a unique signature so that
> > the SOAP processor can figure it out. The SOAP specification doesn't
> > specify how to process more than one child element in the SOAP body.
> > The WS-I Basic Profile has clarified this point and specified a rule
> > that says that the SOAP body must contain at most one child element.
> >
> > When using document/literal, you must wrap your parameters with a
> > single element, and this element must be used as the one and only
> > child element of the SOAP body. If you use the wrapped style, Axis
> > will do this for you automatically.
> >
> > - Anne
> >
> >
> > On Tue, 8 Feb 2005 17:17:01 +0100, David Werner <dave@uni-koblenz.de>
> > wrote:
> >> Hallo Ioan,
> >>
> >> I'm quite stunned by this bug! Handling multiple parameters should be
> >> a
> >> basic functionality.
> >> In any case, many thanks for your reply! :-)
> >>
> >> Ciao, Dave
> >>
> >>
> >>> -----Original Message-----
> >>> From: Ioan Berbece [mailto:iberbece@kana.com]
> >>> Sent: Monday, February 07, 2005 8:50 PM
> >>> To: axis-user@ws.apache.org
> >>> Subject: RE: Can't invoke method with multiple arguments
> >>>
> >>>
> >>> Hi Dave,
> >>>
> >>> Last time I checked Axis 1.1 and Axis 1.2 RC2 didn't handle multiple
> >>> message parts in a doc/lit web service. Take a look at this bug:
> >>> http://issues.apache.org/jira/browse/AXIS-621
> >>> which has an attachment for an attempted fix in Call.java (client
> >>> side).
> >>> I also attempted a fix for the server side in RPCProvider.java, but
> >>> I'm
> >>> not sure whether the fix is a proper one (although the functional
> >>> tests
> >>> pass with the fix in place in Axis 1.2 RC2).
> >>> I have to say here that I'm a bit disappointed to see that this bug
> >>> (and
> >>> I believe there are others related) hasn't received the attention it
> >>> requires (right now it seems it spans two versions: 1.1 and 1.2 - not
> >>> sure what the story is in Axis 2.0).
> >>> If you want my proposed fix email me privately.
> >>>
> >>> Thanks,
> >>> IB
> >>>
> >>> -----Original Message-----
> >>> From: David Werner [mailto:dave@uni-koblenz.de]
> >>> Sent: February 7, 2005 1:50 PM
> >>> To: axis-user@ws.apache.org
> >>> Subject: RE: Can't invoke method with multiple arguments
> >>>
> >>> Hallo,
> >>>
> >>> I also tried to invoke the same service with a Call object and
> >>> explicitly
> >>> set the type of the parameters. This time I got anothter exception:
> >>> "org.xml.sax.SAXException: SimpleDeserializer encountered a child
> >>> element,
> >>> which is NOT expected, in something it was trying to deserialize."
> >>> Does anyone have an idea ...?
> >>>
> >>> Bye, Dave
> >>>
> >>> --------------------
> >>>  client code
> >>> --------------------
> >>>
> >>> public class TestClient2
> >>> {
> >>>   public static void main(String [] args) {
> >>>     try {
> >>>        String endpoint =
> >>>          "http://localhost:1234/axis1.2rc2/services/test";
> >>>
> >>>        Service  service = new Service();
> >>>        Call     call    = (Call) service.createCall();
> >>>
> >>>        call.setTargetEndpointAddress( new java.net.URL(endpoint) );
> >>>        call.setOperationName(new QName("urn:TestNS", "printLongs") );
> >>>
> >>>        call.addParameter("in6",
> >>>                          org.apache.axis.Constants.XSD_LONG,
> >>>                          javax.xml.rpc.ParameterMode.IN);
> >>>        call.addParameter("in7",
> >>>                          org.apache.axis.Constants.XSD_LONG,
> >>>                          javax.xml.rpc.ParameterMode.IN);
> >>>        call.setReturnType(org.apache.axis.Constants.XSD_STRING);
> >>>        String response = (String) call.invoke( new Object[] { 1L, 1L
> >>> }
> >>> );
> >>>        System.out.println(response);
> >>>     } catch (Exception e) {
> >>>        System.err.println(e.toString());
> >>>     }
> >>>   }
> >>> }
> >>>
> >>> --------------------
> >>>  exception
> >>> --------------------
> >>>
> >>> AxisFault
> >>>  faultCode:
> >>> {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
> >>>  faultSubcode:
> >>>  faultString: org.xml.sax.SAXException: SimpleDeserializer
> >>> encountered a
> >>> child element, which is NOT expected, in something it was trying to
> >>> deserialize.
> >>>  faultActor:
> >>>  faultNode:
> >>>  faultDetail:
> >>>
> >>> {http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException:
> >>> SimpleDeserializer encountered a child element, which is NOT
> >>> expected,
> >>> in
> >>> something it was trying to deserialize.
> >>>   at
> >>> org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDe
> >>> ser
> >>> iali
> >>> zer.java:143)
> >>>   at
> >>> org.apache.axis.encoding.DeserializationContext.startElement(Deserial
> >>> iza
> >>> tion
> >>> Context.java:1031)
> >>>   at
> >>> org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.ja
> >>> va:
> >>> 165)
> >>>   at
> >>> org.apache.axis.message.MessageElement.publishToHandler(MessageElemen
> >>> t.j
> >>> ava:
> >>> 1140)
> >>>   at
> >>> org.apache.axis.message.RPCElement.deserialize(RPCElement.java:238)
> >>>   at
> >>> org.apache.axis.message.RPCElement.getParams(RPCElement.java:386)
> >>>   at
> >>> org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider
> >>> .ja
> >>> va:1
> >>> 48)
> >>>   at
> >>> org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:
> >>> 319
> >>> )
> >>>   at
> >>> org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrateg
> >>> y.j
> >>> ava:
> >>> 32)
> >>>   at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
> >>>   at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
> >>>   at
> >>> org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:
> >>> 450)
> >>>   at org.apache.axis.server.AxisServer.invoke(AxisServer.java:285)
> >>>   at
> >>> org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:
> >>> 653)
> >>>   at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
> >>>   at
> >>> org.apache.axis.transport.http.AxisServletBase.service(AxisServletBas
> >>> e.j
> >>> ava:
> >>> 301)
> >>>   at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
> >>>   ....
> >>>
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: David Werner [mailto:dave@uni-koblenz.de]
> >>>> Sent: Monday, February 07, 2005 3:35 PM
> >>>> To: Axis-User@Ws. Apache. Org
> >>>> Subject: Can't invoke method with multiple arguments
> >>>>
> >>>>
> >>>> Hi,
> >>>>
> >>>> I haven't realized the whole problem, when I submitted the mail
> >>>> with subject
> >>>> 'Problem with deserealizing boolean'. In fact, I can't invoke any
> >>> method
> >>>> with more than a single argument, independent of the arguments'
> >>> (simple)
> >>>> type! A java.lang.IllegalArgumentException is thrown, because
> >>>> only the first
> >>>> value can be deseserialized:
> >>>>
> >>>> "Tried to invoke method public java.lang.String
> >>>> test.server.TestSoapBindingImpl.printLongs(long,long) with arguments
> >>>> java.lang.Long,null. The arguments do not match the signature."
> >>>>
> >>>> Here's an example of a simple web service, that takes two longs and
> >>> should
> >>>> return a string.
> >>>> At the end of the mail I copied a part of Axis' log file, where only
> >>> the
> >>>> first argument of printLongs is properly converted before the
> >>> exception is
> >>>> thrown.
> >>>> I would be really glad, if someone could give me a hint of what I'm
> >>> doing
> >>>> wrong. ;-)
> >>>>
> >>>> BTW, I'm using Axis 1.2RC2, Tomcat 5.0.19 and JDK 1.5 on Win XP.
> >>>>
> >>>> Bye, Dave
> >>>>
> >>>> -------------------------
> >>>>  service implementation
> >>>> ------------------------
> >>>> public class TestSoapBindingImpl implements test.server.Test{
> >>>>
> >>>>   public String printLongs(long long_1, long long_2){
> >>>>     return "long_1 = " +long_1 +", long_2 = " +long_2;
> >>>>   }
> >>>>
> >>>> }
> >>>>
> >>>> --------------------
> >>>>  client
> >>>> --------------------
> >>>> public class TestClient {
> >>>>
> >>>>   public static void main (String[] args) throws Exception {
> >>>>     TestService service = new TestServiceLocator();
> >>>>     Test testProxy = service.gettest();
> >>>>
> >>>>     long longVal = 1L;
> >>>>     response = testProxy.printLongs(longVal, longVal);
> >>>>     System.out.println(response);
> >>>>   }
> >>>> }
> >>>>
> >>>> --------------------
> >>>>  SOAP messsage
> >>>> --------------------
> >>>> <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>
> >>>>       <in6 xmlns="urn:TestNS">1</in6>
> >>>>       <in7 xmlns="urn:TestNS">1</in7>
> >>>>    </soapenv:Body>
> >>>> </soapenv:Envelope>
> >>>>
> >>>>
> >>>> -----------------
> >>>>  Axis' log file
> >>>> -----------------
> >>>>        ...
> >>>> 17555  org.apache.axis.message.SAXOutputter
> >>>>         - SAXOutputter.startElement ['urn:TestNS' in6]
> >>>> 17555  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>>> org.apache.axis.i18n.resource::handleGetObject(startElem00)
> >>>> 17555  org.apache.axis.encoding.SerializationContext
> >>>>         - Start element [urn:TestNS]:in6
> >>>> 17555  org.apache.axis.message.SAXOutputter
> >>>>         - SAXOutputter.characters ['1']
> >>>> 17766  org.apache.axis.message.SAXOutputter
> >>>>         - SAXOutputter.endElement ['urn:TestNS' in6]
> >>>> 17766  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(endElem00)
> >>>> 17766  org.apache.axis.encoding.SerializationContext
> >>>>         - End element in6
> >>>> 17766  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(empty00)
> >>>> 17766  org.apache.axis.utils.NSStack
> >>>>         - NSPop (empty)
> >>>> 17766  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(bodyIs00)
> >>>> 17766  org.apache.axis.providers.java.RPCProvider
> >>>>         - body is <in6 xmlns="urn:TestNS">1</in6>
> >>>> 17766  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>> org.apache.axis.i18n.resource::handleGetObject(pushHandler00)
> >>>> 17766  org.apache.axis.encoding.DeserializationContext
> >>>>         - Pushing handler org.apache.axis.message.RPCHandler@82d210
> >>>> 17766  org.apache.axis.encoding.DeserializationContext
> >>>>         - Enter: DeserializationContext::startPrefixMapping(,
> >>> urn:TestNS)
> >>>> 17766  org.apache.axis.utils.NSStack
> >>>>         - NSPush (32)
> >>>> 17766  org.apache.axis.utils.NSStack
> >>>>         - NSPush (32)
> >>>> 17766  org.apache.axis.encoding.DeserializationContext
> >>>>         - Exit: DeserializationContext::startPrefixMapping()
> >>>> 17766  org.apache.axis.encoding.DeserializationContext
> >>>>         - Enter: DeserializationContext::startElement(urn:TestNS,
> >>>> in6)
> >>>> 17766  org.apache.axis.message.RPCHandler
> >>>>         - Enter: RPCHandler.onStartChild()
> >>>> 17766  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>> org.apache.axis.i18n.resource::handleGetObject(typeFromAttr00)
> >>>> 17766  org.apache.axis.message.RPCHandler
> >>>>         - Type from attributes is:  null
> >>>> 17876  org.apache.axis.message.RPCHandler
> >>>>         - Exit: RPCHandler.onStartChild()
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>> org.apache.axis.i18n.resource::handleGetObject(pushHandler00)
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Pushing handler
> >>>> org.apache.axis.encoding.ser.SimpleDeserializer@2c9103
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Exit: DeserializationContext::startElement()
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Enter: DeserializationContext::endElement(urn:TestNS, in6)
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>>> org.apache.axis.i18n.resource::handleGetObject(popHandler00)
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Popping handler
> >>>> org.apache.axis.encoding.ser.SimpleDeserializer@2c9103
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>>> org.apache.axis.i18n.resource::handleGetObject(setValueInTarget00)
> >>>> 17886  org.apache.axis.encoding.DeserializerImpl
> >>>>         - Set value 1 in target
> >>>> org.apache.axis.encoding.MethodTarget@1e46a68
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(empty00)
> >>>> 17886  org.apache.axis.utils.NSStack
> >>>>         - NSPop (empty)
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Popped element stack to
> >>> org.apache.axis.message.SOAPBody:Body
> >>>> 17886  org.apache.axis.encoding.DeserializationContext
> >>>>         - Exit: DeserializationContext::endElement()
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(convert00)
> >>>> 17886  org.apache.axis.utils.JavaUtils
> >>>>         - Trying to convert java.lang.Long to long
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         - org.apache.axis.i18n.resource::handleGetObject(value00)
> >>>> 17886  org.apache.axis.providers.java.RPCProvider
> >>>>         -   value:  1
> >>>> 17886  org.apache.axis.i18n.ProjectResourceBundle
> >>>>         -
> >>> org.apache.axis.i18n.resource::handleGetObject(dispatchIAE00)
> >>>> 17986  org.apache.axis.providers.java.RPCProvider
> >>>>         - Tried to invoke method public java.lang.String
> >>>> test.server.TestSoapBindingImpl.printLongs(long,long) with arguments
> >>>> java.lang.Long,null.  The arguments do not match the signature.
> >>>> java.lang.IllegalArgumentException
> >>>>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> >>>>     at
> >>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorIm
> >>>> pl.java:39
> >>>> )
> >>>>     at
> >>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAc
> >>>> cessorImpl
> >>>> .java:25)
> >>>>     at java.lang.reflect.Method.invoke(Method.java:585)
> >>>>     at
> >>>> org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCProvide
> >>>> r.java:384
> >>>> )
> >>>>       at
> >>>> org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvi
> >>>> der.java:2
> >>>> 81)
> >>>>     at
> >>>>
> >>> org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:
> >>> 319
> >>> )
> >>>>     at
> >>>> org.apache.axis.strategies.InvocationStrategy.visit(InvocationStra
> >>>> tegy.java:
> >>>> 32)
> >>>>     at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
> >>>>     at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
> >>>>     at
> >>>> org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:
> >>>> 450)
> >>>>     at org.apache.axis.server.AxisServer.invoke(AxisServer.java:285)
> >>>>     at
> >>>>
> >>> org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:
> >>> 653)
> >>>>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
> >>>>     at
> >>>> org.apache.axis.transport.http.AxisServletBase.service(AxisServlet
> >>>> Base.java:
> >>>> 301)
> >>>>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
> >>>>   ...
> >>>>
> >>>
> >>>
> >>
> >>
> >>
> Linus Kamb
> linus@iris.washington.edu
> (206) 547-0393 x106
> 
>

Mime
View raw message