Ok, I did a little more testing, and I still suspect the problem to be
somewhere in Muse.

Here's my server code:
    public Element boxOperation(int width) throws Exception
    {
        BoxDocument doc = BoxDocument.Factory.newInstance();
        BoxType type = doc.addNewBox();
        type.setWidth(BigInteger.valueOf(width));
        type.setHeight(BigInteger.valueOf(width));

        Element response = XmlUtils.getFirstElement(doc.newDomNode());
        System.out.println("--BoxCapability toString(response):\n" +
XmlUtils.toString(response));
        return response;
    }

Here's the server output:
    --BoxCapability toString(response):
    <?xml version="1.0" encoding="UTF-8"?>
    <box:Box xmlns:box="http://cisco.com/musebox/schemas/box";>
        <box:width>555</box:width>
        <box:height>555</box:height>
    </box:Box>

On the client side, here's the SOAP trace of the incoming data:
    [CLIENT TRACE] SOAP envelope contents (incoming):
    ...
        <soapenv:Body>
            <muse-op:BoxOperationResponse
                xmlns:muse-op="http://cisco.com/musebox/simple/box";
xmlns:tns="http://ws.apache.org/axis2";>
                <Box xmlns="http://schemas.xmlsoap.org/wsdl/";
xmlns:box="http://cisco.com/musebox/schemas/box";>
                    <box:width>555</box:width>
                    <box:height>555</box:height>
                </Box>
            </muse-op:BoxOperationResponse>
        </soapenv:Body>
    </soapenv:Envelope>

If I modify my wsdl and remove one attribute line
(xmlns="http://schemas.xmlsoap.org/wsdl/";) at the top of the file, I get
the following client side SOAP trace instead:
    [CLIENT TRACE] SOAP envelope contents (incoming):
    ...
    <soapenv:Body>
            <muse-op:BoxOperationResponse
                xmlns:muse-op="http://cisco.com/musebox/simple/box";
xmlns:tns="http://ws.apache.org/axis2";>
                <Box xmlns:box="http://cisco.com/musebox/schemas/box";>
                    <box:width>555</box:width>
                    <box:height>555</box:height>
                </Box>
            </muse-op:BoxOperationResponse>
        </soapenv:Body>
    </soapenv:Envelope>

NOTE: The difference between the two traces are the namespaces in the
<Box> element.

If my client code calls
XmlUtils.toString(XmlUtils.getFirstElement(response)), I get:
    <?xml version="1.0" encoding="UTF-8"?>
    <Box xmlns="http://schemas.xmlsoap.org/wsdl/";
xmlns:box="http://cisco.com/musebox/schemas/box";>
        <box:width>555</box:width>
        <box:height>555</box:height>
    </Box>

So there are 2 problems here:

1) Muse takes my operation output and puts on a response wrapper.  In
doing so, it removes both the namespace and prefix of the <Box> element.
After removing the wrapper, the <Box> element now becomes useless
because it has no namespace, even though namespaces for child elements
are properly preserved.  This is why my client code is running into
errors when trying to serialize the xml element back into a javabean
(XmlBean object).  It tries to find/match the original namespace of the
<Box> element, but it is nowhere to be found.

2) In addition to Muse removing the top element's namespace, it tries to
put in a default one instead.  If my wsdl file contains the attribute
xmlns="http://schemas.xmlsoap.org/wsdl/";
(which is defined in the samples), then Muse will take this namespace
and set it as the default in the <Box> element.  So my client code
complains of a namespace mismatch.  (The namespace
xmlns:tns="http://ws.apache.org/axis2"; is also inserted either by Muse
or Axis2, but it isn't causing problems at this moment.)

So I think Muse should either properly preserve the operation results
exactly as is, or put in the correct element namespaces and not override
incorrectly.  Muse does preserve notification outputs correctly, but it
doesn't seem to do so for operations.

If someone can confirm this as a bug, I'll open a JIRA item.

I also tried to implement serializers for my custom types so that I can
return them directly from the operations, but I seem to be running into
similar issues with namespaces being moved/deleted.  I'll post these
issues in another email.
-Vinh


-----Original Message-----
From: Daniel Jemiolo [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, November 22, 2006 2:43 PM
To: [email protected]
Subject: RE: changed capability result data

It looks like your stack trace is because you're feeding the wrapper
element to XmlBeans instead of the Box element... right? Shouldn't it
be:

public BoxType equipmentOperation(String param1)
        throws SoapFault, Exception
{
        Element body =
XmlUtils.createElement(IEquipmentCapability.OP_QNAME, param1);
        Element response = invoke(IEquipmentCapability.OP_URI, body);

        // this gets the <Box/>, which is what XmlBeans should parse...
        Element boxXML = XmlUtils.getFirstElement(response);

        BoxDocument doc = BoxDocument.Factory.parse(boxXML);
        return doc.getBox();
}


Or am I missing something?

I honestly don't know why the default namespace is being added in. If
you turn on SOAP tracing on the server side (use the nightly build and
set the log level to 'FINE'), the SOAP messages in muse.log will show
you what Muse passes to Axis2 right before control goes back to Axis2.
The XML should be the same that you provided. If it's not, then Muse has
a problem; if so, it's an Axis2 or XML parser problem.

Dan


"Vinh Nguyen \(vinguye2\)" <[EMAIL PROTECTED]> wrote on 11/22/2006
02:35:04 PM:

> Thankyou Dan,
> 
> 1) I'm using XmlBeans to generate pojo classes from xsd's, and I use 
> them both on the server and client.  On the server, the bean has a 
> mechanism for getting the xml representation of itself, which I then 
> pass to Muse.  On the client, the same bean can be recreated from the 
> xml.  The main problem I'm getting is on the server side when my bean 
> tries to parse the incoming xml.  For one, the xml has the "response"
> wrapper, so I have to find a way to use the child node below it.  And 
> second, the child node's xml representation has changed from what was 
> passed on the server side.
> 
> Here's the server code:
> 
> public class EquipmentCapability extends AbstractCapability implements

> IEquipmentCapability {
>     public Element equipmentOperation(String param1) throws Exception
>     {
>         // Get the EPR id of this capability's resource.
>         // For now, assume that a parameter value is set which 
> contains the EPR ID.
>         MessageHeaders headers =
> getEnvironment().getAddressingContext();
>         EndpointReference epr = headers.getToAddress();
>         String eprID = epr.getParameters()[0].getTextContent();
> 
>         // Store the EPR id in the response object so that we can 
> identify which resource EPR this capability was invoked on.
>         BoxDocument doc = BoxDocument.Factory.newInstance();
>         BoxType type = doc.addNewBox();
>         type.setName("EPR ID: " + eprID);
> 
>         System.out.println("--XmlUtils.toString(doc.newDomNode()):\n" 
> + XmlUtils.toString(doc.newDomNode()));
>         return XmlUtils.getFirstElement(doc.newDomNode());
>     }
> }
> 
> Here's the client code:
> 
> public class SimpleEquipmentClient extends WsResourceClient {
>     public BoxType equipmentOperation(String param1)
>     throws SoapFault, Exception
>     {
>         Element body =
> XmlUtils.createElement(IEquipmentCapability.OP_QNAME, param1);
>         Element response = invoke(IEquipmentCapability.OP_URI, body);
>         System.out.println("response:\n" + 
> XmlUtils.toString(response));
> 
>         //EquipmentOperationResponseDocument doc = 
> EquipmentOperationResponseDocument.Factory.parse(response);
>         //BoxType type = doc.getEquipmentOperationResponse().getBox();
>         BoxDocument doc = BoxDocument.Factory.parse(response);
>         BoxType type = doc.getBox();
> 
>         return type;
>     }
> }
> 
> Here's the server console output:
> 
> --XmlUtils.toString(doc.newDomNode()):
> <?xml version="1.0" encoding="UTF-8"?> <box:Box 
> xmlns:box="http://cisco.com/musebox/schemas/box";>
>     <box:name>EPR ID: MuseResource-2</box:name> </box:Box>
> 
> Here's the client console output:
> 
> response:
> <?xml version="1.0" encoding="UTF-8"?> 
> <muse-op:EquipmentOperationResponse
>     xmlns:muse-op="http://cisco.com/musebox/cap/equip";
> xmlns:tns="http://ws.apache.org/axis2";>
>     <Box xmlns="http://schemas.xmlsoap.org/wsdl/";
> xmlns:box="http://cisco.com/musebox/schemas/box";>
>         <box:name>EPR ID: MuseResource-2</box:name>
>     </Box>
> </muse-op:EquipmentOperationResponse>
> 
> org.apache.xmlbeans.XmlException: Element 
> [EMAIL PROTECTED]://cisco.com/musebox/cap/equip is not a

> valid [EMAIL PROTECTED]://cisco.com/musebox/schemas/box document or a valid 
> substitution.
>    at
>
org.apache.xmlbeans.impl.store.Locale.autoTypeDocument(Locale.java:322)
>    at
>
org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1384)
>    at
>
org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1363)
>    at
> org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeL
> oa
> derBase.java:370)
>    at
> com.cisco.musebox.schemas.box.BoxDocument$Factory.parse(Unknown
Source)
>    at
> com.cisco.musebox.client.proxy.SimpleEquipmentClient.equipmentOperatio
> n(
> SimpleEquipmentClient.java:42)
>    at
>
com.cisco.musebox.client.test.ResourceFacadeTest.run(ResourceFacadeTest.
> java:70)
>    at
> com.cisco.musebox.client.test.Main.testResourceFacade(Main.java:44)
>    at com.cisco.musebox.client.test.Main.main(Main.java:23)
> 
> 
> In the client code, the EquipmentOperationResponseDocument object that

> I commented out is also created from XmlBeans using the resource wsdl.

> If I use this object instead to parse the response, I get a null 
> BoxType reference from it because it seems to be unable to parse out 
> the <Box> element from the xml.  I suspect this is because XmlBeans 
> has some issues with certain usage patterns of namespaces and 
> prefixes.  But, if the xml was received the same way it was created 
> from my bean, it should be able to parse it correctly.  So the issue 
> is why it is changing from the server to the client.  If I need to, I 
> can try to trace the core code at some point later to know for sure 
> where the problem is happenning.
> 
> 2) To get around this problem, I can create serializers for each of 
> the pojo types.  I would like to find a generic way to do it though, 
> if I can get away from explicitly identifying each serializer class in

> the muse.xml somehow.  If not, I may have to do just that, and 
> hopefully maintenence won't get too difficult in the long run when 
> more types are created.
> 
> 
> -----Original Message-----
> From: Daniel Jemiolo [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, November 22, 2006 7:15 AM
> To: [email protected]
> Subject: RE: changed capability result data
> 
> 1. I suppose Muse does strip your wrapper element out, but it's not 
> really expecting it in the first place - the Java return type is 
> supposed to be serialized and then added to the response message, so 
> the user isn't expected to handle the wrapper SOAP. If you really want

> to handle the wrapper SOAP you can create a custom MessageHandler for 
> this, but given the other behavior, I don't think this would solve 
> your problem.
> 
> 2. Here we have to look at what Java requires. Web services allow for 
> multiple return values, but Java does not; if we want to return 
> multiple values in Java, we either use a Collection or, if the values 
> are all related (usually they are), we made a simple wrapper class. 
> Since SOAP + Collections has never been well-defined or especially 
> interoperable, I suggest the latter. Make a wrapper type that has the 
> N elements you want, and create a Java class from that. The Java class

> can then have getter methods to expose the different fields.
> 
> 3. The Muse code is pretty sensitive to the issue of prefix and 
> namespace combinations - we don't like to modify anyone's 
> prefix/namespaces because that can make some parts of a WSRF-based 
> message unresolvable. Axis2 used to do this and we had a big hack in 
> place to workaround it; they've fixed it now, so that means both Muse 
> and Axis2 should be leaving your XML alone. On the client side, Muse 
> just reads in your XML as bytes from an InputStream and uses
> XmlUtils.createDocument() to make the DOM Element (which just uses 
> Xerces, there's not pre-modification).
> 
> Where exactly is the XmlBeans stuff being used? Just client side? Or 
> on the server side?
> 
> Have you had any luck creating the Elements with
> XmlUtils.createELement() vs. building a string literal?
> 
> 4. Is your XmlBeans code boilerplate-like? That is, does look the same

> whether you're serializing a Box or some other custom type? If so, let

> me know what the code looks like (I'm not an XmlBeans user), and I can

> suggest a way to fit it into the Serializer framework so that 
> supporting many types isn't such a burden but you still get the 
> benefit of a real Java programming model.
> 
> Dan
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to