[
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]