[ 
https://issues.apache.org/jira/browse/AXIS2-1938?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12468050
 ] 

Bo Xie commented on AXIS2-1938:
-------------------------------

Looks like this is related with xsd resource loading on the service side. This 
kinda explain why the same code worked on client side(with the xsi:type 
generated) but not on the service side. Update with more info on the email 
thread.

Thanks,
-Bo

Hi,

   My previous issue is caused by org.apache.xmlbeans.impl

    .schema.SchemaTypeLoaderImpl's findTypeRef () not be able to load the 
following resource in service: 


schemaorg_apache_xmlbeans/type/http_3A_2F_2Fquickstart_2Esamples_2Fxsd/EU_2DAddress.xsb

This resource is actually in my .aar file under 
dir\XBean-packaged.jar(generated from WSDL2JAVA)

Do anyone know how to make it work?

Thanks a lot!

-Bo



On 1/21/07, Bo Xie <[EMAIL PROTECTED] > wrote:

    Hi all,

        Sorry to ask this again, does anyone know what could cause the 
following call to return null, is it some kind of setup/configure issue in the 
service? How to workaround it? It is in 
org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl's findTypeRef (). This 
causes the derived type cannot be created properly with the xsi:type attribute.

        SchemaTypeSystem ts = typeSystemForComponent("schema" + 
METADATA_PACKAGE_LOAD + "/type/", name);


    Thanks,
    -Bo



    On 1/19/07, Bo Xie <[EMAIL PROTECTED] > wrote:

        Hi,

          Looks like the problem is with the _typeCache in 
org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl's findTypeRef () not being 
populated correctly for derived type when deployed as a service. This in turn 
was caused by typeSystemForComponent() in findTypeRef() returning null. As 
comparison, the _typeCache is populated correctly if I run it locally in a test 
program's main() and in this case the typeSystemForComponent() is not null.

          Below is the findTypeRef method which suppose to return the derived 
type if Qname passed in is a derived type. In my case, the QName is { 
http://quickstart.samples/xsd}EU-Address .

          When in service, the _typeCache is populated with CACHED_NOT_FOUND 
for QName {http://quickstart.samples/xsd}EU-Address . So findTypeRef  will 
return null. This will result in the changeType() call to not return the 
derived type. (See call stack at the bottom.)

          In the local test program, the _typeCache was initially empty and was 
populated with the correct value at the end of findTypeRef call.

          The only way that CACHED_NOT_FOUND can be set for any QName type is 
when the following line in findTypeRef () return null.
        SchemaTypeSystem ts = typeSystemForComponent("schema" + 
METADATA_PACKAGE_LOAD + "/type/", name);

          I have no idea why this typeSystemForComponent() could return null in 
service. Can someone help clarify the myth here? When I trace into the first 
incoming message, it indeed shows that the typeSystemForComponent return null!

          Below are the findTypeRef method and the call stack.

        Thanks,
        -Bo

        public SchemaType.Ref findTypeRef(QName name)
            {
                /**
                 * The maps are synchronized, we use two accesses to the cache 
(one read
                 * and one write), but the code inbetween is not synchronized. 
The
                 * assumption is that the underlying datastructures (the search 
path and
                 * the classloader) do not change, so two threads running the 
code in
                 * parallel will come up with the same result.
                 */
                Object cached = _typeCache.get(name);
                if (cached == CACHED_NOT_FOUND)
                    return null; ==>exit here in bad one
                   
                SchemaType.Ref result = (SchemaType.Ref) cached;
                if (result == null)
                {
                    for (int i = 0; i < _searchPath.length; i++)
                        if (null != (result = _searchPath[i].findTypeRef(name)))
                            break;
                    if (result == null)
                    {
                        SchemaTypeSystem ts = typeSystemForComponent("schema" + 
METADATA_PACKAGE_LOAD + "/type/", name);
                        if (ts != null)
                        {
                            result = ts.findTypeRef(name);
                            assert(result != null) : "Type system registered 
type " + QNameHelper.pretty(name) + " but does not return it";
                        }
                    }
                    _typeCache.put(name, result == null ? CACHED_NOT_FOUND : 
result);
                }
                return result; ==>exit here in good case when the typeCache.put 
is call with good value.
            }


        Stack:
        SchemaTypeLoaderImpl.findTypeRef(QName) line: 369   
        SchemaTypeLoaderImpl(SchemaTypeLoaderBase).findType(QName) line: 119   
        SchemaTypeImpl.getElementType(QName, QName, SchemaTypeLoader) line: 910 
  
        
GetAddressesResponseDocumentImpl$GetAddressesResponseImpl(XmlObjectBase).get_element_type(QName,
 QName) line: 925   
        Cur.setType(SchemaType, boolean) line: 2546   
        Xobj$ElementXobj(Xobj).change_type(SchemaType) line: 1876   
        AddressImpl(XmlObjectBase).changeType(SchemaType) line: 504   
        StockQuoteServiceSkeleton.populateAddress(GetAddressesResponseDocument) 
line: 281   
        StockQuoteServiceSkeleton.getAddresses(GetAddressesDocument) line: 226  
 
        
StockQuoteServiceMessageReceiverInOut.invokeBusinessLogic(MessageContext, 
MessageContext) line: 73   
        
StockQuoteServiceMessageReceiverInOut(AbstractInOutSyncMessageReceiver).receive(MessageContext)
 line: 39   
        AxisEngine.receive(MessageContext) line: 493   


        On 1/18/07, Bo Xie < [EMAIL PROTECTED]> wrote:

            Hi,

               Regarding the instanceOf issue, I debugged and saw the following 
issue.

               1. In the WSDL2JAVA generated 
GetAddressesDocumentImpl.getAddressArray, I would expect the array element 
should be of type USAddressImpl if instance is a US address. This is not the 
case. For example, all elements in targetList filled by 
find_all_element_users() are instances of AddressImpl not USAddressImpl when 
the XML element is as follows:

            <xml-fragment xsi:type="xsd:US-Address" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xmlns:xsd=" 
http://quickstart.samples/xsd"; 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/ ">
              <city xmlns=" http://quickstart.samples/xsd";>Cupertino</city>
              <name xmlns="http://quickstart.samples/xsd ">XYZ</name>
              <state xmlns=" http://quickstart.samples/xsd";>CA</state>
              <zip xmlns="http://quickstart.samples/xsd ">95014</zip>
            </xml-fragment>

            This kind of explained why the instanceof is not working properly 
in service code. Any idea why it is done this way? Is it a bug?

            public samples.quickstart.service.xmlbeans.xsd.Address[] 
getAddressesArray()
                    {
                        synchronized (monitor())
                        {
                            check_orphaned();
                            java.util.List targetList = new 
java.util.ArrayList();
                            get_store().find_all_element_users(ADDRESSES$2, 
targetList);
                            samples.quickstart.service.xmlbeans.xsd.Address[] 
result = new samples.quickstart.service.xmlbeans.xsd.Address 
[targetList.size()];
                            targetList.toArray(result);
                            return result;
                        }
                    }

            Thanks,
            -Bo


> [axis2] WSDL2JAVA with XMLBean binding does not create instance of the 
> derived type or ignore xsi:type in the xml
> -----------------------------------------------------------------------------------------------------------------
>
>                 Key: AXIS2-1938
>                 URL: https://issues.apache.org/jira/browse/AXIS2-1938
>             Project: Axis 2.0 (Axis2)
>          Issue Type: Bug
>          Components: databinding
>    Affects Versions: 1.1
>         Environment: Windows XP, tomcat 5.5, Axis2 1.1
>            Reporter: Bo Xie
>         Attachments: StockQuoteServiceSkeleton.java, XMLBeanBinding.zip
>
>
> There are basically two issues.
> 1. The java objects created does not use the xsi:type in the XML. In my case, 
> the xsi:type is for derived type, but the object created is still of base 
> type.
> 2. The XML string generated from the client side has the xsi:type for Address 
> object, so the service see it but did not generate the derived type according 
> to the xsi:type(this is the issue reported above). But the server side 
> generated XML string does not have the xsi:type for the objects, so the 
> object XML string does not have xsi:type when the message received on the 
> client side. Why the xsi:type is missing in this case? In both cases, I used 
> types derived from the Address type. The client and service code are based on 
> the XMLBean quickstart sample.
> Attached are 
> 1. the WSDL file. 
> 2.The build file that you can check if the WSDL2JAVA is proper for my case.
> 3. The client code
> 4. The server code.
> Below are the email exchange with Ajith Ranabahu.
> Subject: [axis2] WSDL2JAVA with XMLBean binding does not create instance of 
> the derived type
> ------------------------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Tue, Jan 2, 2007 at 7:45 PM
> Hi there,
>   I am new to axis2 with XMLBean data binding, please help me with the 
> following issue.
>   I modified the quickstart sample XMLBean program to try a WSDL with the 
> following types. The type US-Address is a derived from type Address. I would 
> like to create a service operation updateAddresses to change addresses of a 
> company based on a symbol. The addresses is an array that can take either 
> Address or USAddress instances.
>           <xs:complexType name="Address">
>                 <xs:sequence>
>                     <xs:element name="name" type="xs:string" minOccurs="0"/>
>                     <xs:element name="street" type="xs:string"/>
>                     <xs:element name="city" type="xs:string"/>
>                 </xs:sequence>
>             </xs:complexType>
>          
>        
>             <xs:complexType name="US-Address">
>                 <xs:complexContent>
>                     <xs:extension base="ipo:Address">
>                         <xs:sequence>
>                             <xs:element name="state" type="ipo:US-State"/>
>                             <xs:element name="zip" type="xs:positiveInteger"/>
>                         </xs:sequence>
>                     </xs:extension>
>                 </xs:complexContent>
>             </xs:complexType>
>          <xs:element name="updateAddresses">
>                 <xs:complexType>
>                     <xs:sequence>
>                         <xs:element name="symbol" type="xs:string" 
> nillable="true"/>
>                         <xs:element name="addresses" type="ipo:Address" 
> maxOccurs="unbounded"/>
>                     </xs:sequence>
>                 </xs:complexType>
>       I used WSDL2JAVA with XMLBean data binding to generate the skeleton and 
> stub code. All looks great and the SOAP exchange looks fine too.
>       In the client code, I created one instance if USAddress and one 
> instance of Address and put them into the addresses list. In the SOAP request 
> message, the instances are as  shown as follows below. Note, xsi-type for the 
> instance indicate the correct types which is nice.
>     <soapenv:Body>
>     <updateAddresses xmlns="http://quickstart.samples/xsd";>
>       
>         <symbol>XYZ</symbol>      
>         <addresses xmlns:xsi="http;//www.w3.org/2001/XMLSchema-instance" 
> xmlns:xsd="
> http://quickstart.samples/xsd"; xsi:type="xsd:US-Address">
>         <name>company name</name>
>         <city>Sunnyvale</city>
>         <state>CA</state>
>         <zip>94087</zip>
>        </addresses>
>        <addresses xmlns:xsi="http;//www.w3.org/2001/XMLSchema-instance" 
> xmlns:xsd="http://quickstart.samples/xsd
> " xsi:type="xsd:Address">
>         <name>company name</name>
>         <city>Hong Kong</city>
>        </addresses>
>     </updateAddresses>
>   </soapenv:Body>
>    The problem is when the XML object mapped into java object on the service 
> side, all the XML address object passed to the skeleton are all of Address 
> type. I would expect one instance be Address type, another be USAddress type. 
> Since xsi-type in the SOAP message has the right type, why the XMLBean object 
> is not created as the derived type? Is there any option in WSDL2JAVA to make 
> this work?
>    From the XMLBean Address java object, how can I access the xsi-type 
> attribute that was available in the XML string?
>    If I am not heading the right direction, can anyone suggest some 
> alternatives?
> Thanks for your time!
> -Bo
>  
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 5:16 AM
> Hi,
> The reason here is that you have set the type of the addresses element
> to be 'Address' rather than USAddress (the code generator would put
> the reference for the Address rather than the USAddress). However
> since the xsi:type attribute is present the deserializer should create
> the right object and you can just use a type cast to get to the right
> object.
> HTH
> Ajith
> [Quoted text hidden]
> --
> Ajith Ranabahu
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 7:55 AM
> Thanks Ajith for the quick response.
> I have tried to use the instanceof to test if the instance is USAddress,
> but the test returns false. Without that, the type cast is not safe as
> the Address list can have items of either Address or USAddress. My
> question here is should the java instance created from XML be of type
> USAddress even though the signature is Address. Is there anyway to make
> this happen?
> Thanks,
> -Bo
> [Quoted text hidden]
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 8:20 AM
> Hi,
> Since the xsi:type attribute is present and points to the USAddress,
> the generated object should be of  type USAddress. Perhaps the problem
> is the way you check the instanceof. I mean XMLBeans should have
> generated a getAddresses method to updateAddress ? (It's a little bit
> weird how XMLBeans treats these schemas but I'm guessing)
> If you can use a debugger and go through the object hierarchy at
> runtime you should be able to figure this out
> Ajith
> [Quoted text hidden]
> --
> Ajith Ranabahu
> [Quoted text hidden]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 10:19 AM
> Thanks Ajith. Could you be more specific on how to figure out the right type 
> of the instance? Here is the code snippet and the output on the service side.
> The getAddressArray indeed returns Address[] which is good. But the 
> instanceof always returns Address even for USAddress instance. The 
> interesting thing is the toString output of the addr variable. It includes 
> the correct xsi-type for each instance. So how can I do the correct 
> instanceof to figure the right type to cast in this case?
> Thanks,
> -Bo
> ----Code snippet----
> public  void 
> updateAddresses(samples.quickstart.service.xmlbeans.xsd.UpdateAddressesDocument
>  param3)
>     {
>         //Todo fill this with the necessary business logic
>         String symbol = param3.getUpdateAddresses().getSymbol();
>         System.err.println(getCurrentTime()+"- Update Symbol:" + symbol);
>        
>         Address[] addrs = param3.getUpdateAddresses ().getAddressesArray();
>         for (int i = 0; i < addrs.length; i++) {
>             Address addr = addrs[i];
>             if(addr instanceof USAddress) System.err.println("USAddress 
> instance");
>             if(addr instanceof Address) System.err.println("Address 
> instance");
>             System.err.println(addr.getClass().getName()+":"+addr);
>         }
>    ...}
>  ----Output from the code ----
> Address instance
> samples.quickstart.service.xmlbeans.xsd.impl.AddressImpl: <xml-fragment 
> xsi:type="xsd:US-Address" 
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:xsd=" 
> http://quickstart.samples/xsd"; 
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";>
>   <name xmlns=" http://quickstart.samples/xsd";>company name</name>
>   <city xmlns="http://quickstart.samples/xsd";>Sunnyvale</city>
>   <state xmlns=" http://quickstart.samples/xsd";>CA</state>
>   <zip xmlns="http://quickstart.samples/xsd";>94087</zip>
> </xml-fragment>
> Address instance
> samples.quickstart.service.xmlbeans.xsd.impl.AddressImpl:<xml-fragment 
> xsi:type="xsd:Address" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"; 
> xmlns:ns1="http://quickstart.samples/xsd"; 
> xmlns:xsd="http://quickstart.samples/xsd " 
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";>
>   <name xmlns="http://quickstart.samples/xsd ">company</name>
>   <city xmlns="http://quickstart.samples/xsd";>Hong Kong</city>
> </xml-fragment>
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 5:16 PM
> Hi,
> It seems to me that you have to go one level deep. See whether there
> is a getAddress method in the Address class.
> XMLBeans generates a lot of classes and things are a bit confusing
> specially when types and elements have similar names. AFAIK XMLBeans
> generates a class per type and element. So there would be a class
> generated for the address type and also for the address element. My
> guess is you have to check the address type object instead of the
> address element object.
> Ajith
> [Quoted text hidden]
> --
> [Quoted text hidden]
> --------
> From: Ramesh Gurunathan <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 8:32 PM
> Hi,
> What you are trying to achieve is the value inheritance in XML. I
> think, unfortunately, the web services / XML / SOAP community is
> paying less attention to this topic. I encountered the same issue with
> XMLBeans binding. It forced me to change the XML schema. I introduced
> a new complex type with a 'choice'
> <complexType name="Address">
>  <choice>
>    <element name="USAddress" type="USAddress"/>
>    <element name="OtherAddress" type="OtherAddress"/>
>  </choice>
> </complexType>
> <xs:complexType name="OtherAddress">
>  <xs:sequence>
>    <xs:element name="name" type="xs:string" minOccurs="0"/>
>    <xs:element name="street" type="xs:string"/>
>    <xs:element name="city" type="xs:string"/>
>  </xs:sequence>
> </xs:complexType>
> <xs:complexType name="USAddress">
>  <xs:complexContent>
>    <xs:extension base="ipo:OtherAddress">
>      <xs:sequence>
>        <xs:element name="state" type="ipo:US-State"/>
>        <xs:element name="zip" type="xs:positiveInteger"/>
>      </xs:sequence>
>   </xs:extension>
>  </xs:complexContent>
> </xs:complexType>
> <xs:element name="updateAddresses">
>  <xs:complexType>
>    <xs:sequence>
>      <xs:element name="symbol" type="xs:string" nillable="true"/>
>      <xs:element name="addresses" type="Address" maxOccurs="unbounded"/>
>    </xs:sequence>
>  </xs:complexType>
> </element>
> If you generate XML beans types with above changes, it will generate a
> Address type object which will have methods to check whether USAddress
> is set or the Other Address. No need of instanceof check. Do take a
> look at the generated method signatures of the Address XML type
> object, it should give you an idea to play with it.
> That said, this is just an another way of handling inheritance. I
> would like to see XML beans to inherantly support the polymorphism.
> Ramesh
> [Quoted text hidden]
> --------
> From: Bo Xie <[EMAIL PROTECTED]>
> To: [email protected]
> Date: Wed, Jan 3, 2007 at 10:50 PM
> Hi Ajith,
>    The Address class only has getter and setter for name, city etc. No 
> getAddress. Do you see this ignoring of xsi:type in creating instance as a 
> bug?
>    Besides using choice option as Ramesh suggested, do we run out of luck 
> here? I am a little hesitate to use choice as in my case, the choice list 
> changes quite fast. Keeping track of the exhaustive list of all the choices 
> is a challenge.
> Thanks,
> -Bo
> [Quoted text hidden]
> --------
> From: Ajith Ranabahu <[EMAIL PROTECTED]>
> Reply-To: [email protected]
> To: [email protected]
> Date: Thu, Jan 4, 2007 at 5:08 AM
> Hi,
> > Hi Ajith,
> >
> >    The Address class only has getter and setter for name, city etc. No
> > getAddress. Do you see this ignoring of xsi:type in creating instance as a
> > bug?
> Yep. It is a bug. But AFAIK it was reported to be working. In any case
> you can file a Jira with your schema.
> Ajith

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


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

Reply via email to