You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by qzpmwo qzpmwo <qz...@gmail.com> on 2009/07/18 15:21:04 UTC

Possible problem with JAXB marshalling

Hi,

I'm having a strange problem with CXF RESTful service marsahlling base and
derived xsd types.

XSD:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
    targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
    elementFormDefault="unqualified" jaxb:version="2.0">

   <xs:complexType name="BaseType">
      <xs:sequence>
      </xs:sequence>
   </xs:complexType>

   <xs:complexType name="DerivedType">
      <xs:complexContent>
         <xs:extension base="BaseType">
            <xs:sequence>
            </xs:sequence>
         </xs:extension>
     </xs:complexContent>
   </xs:complexType>

   <xs:complexType name="ListType">
      <xs:sequence>
               <xs:element name="item" type="BaseType" minOccurs="0"
maxOccurs="unbounded" />
      </xs:sequence>
   </xs:complexType>

   <xs:element name="base" type="BaseType" />
   <xs:element name="derived" type="DerivedType" />
   <xs:element name="list" type="ListType" />

</xs:schema>

xjc has been used to jenerate java code from xsd. After that:

1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
annotations have been added to BaseType java class code
2) @XmlRootElement has been added to DerivedType java class code
3) @XmlRootElement has been added to ListType java class code

When my CXF rest service returns list of the Derived objects it produces xml
correctly:

<list>
    <base xsi:type="DerivedType">...</base>
    ...
    <base xsi:type="DerivedType">...</base>
</list>

But when I'm requesting 1 instance of the Derived object XML is wrong (as I
understand)

<derived>...</derived>

Since I did not specify substitution group in my opinion xml should be like
in list:

<base xsi:type="DerivedType">...</base>

Could you please clarify the issue for me and may be help me to solve this
problem.

Forgot to mention that I'm using CXF 2.2

Thanks in advance
--- Karen

Re: Possible problem with JAXB marshalling

Posted by qzpmwo qzpmwo <qz...@gmail.com>.
Hi,

Cool, I will do the same since changing CXF version now is probably not
feasible for us now.

Thanks
--- Karen

On Tue, Jul 21, 2009 at 3:08 PM, Sergey Beryozkin <sergey.beryozkin@iona.com
> wrote:

>
> Hi,
>
> No problems and thanks for raising this issue on this list -  I reckon
> we've
> ended up adding a pretty useful feature (optional JAXBElement wrapping) to
> the default JAXBElementProvider wich can be generally useful.
>
> By the way, that workaround I mentioned is a bit hacky though doable - but
> a
> simpler workaround would be to create a custom JAXBElementProvider which
> extends the default one and overrides
>
> protected void marshal(Object obj, Class<?> cls, Type genericType,
>                           String enc, OutputStream os, MediaType mt)
>
> the way it's done currently on the trunk, perhaps explicitly checking for
> BaseType
>
>
> cheers, Sergey
>
> Qzpmwo wrote:
> >
> > Hi Sergey,
> >
> > I'm really impressed with your help!
> >
> > Thanks a lot
> > --- Alex
> >
> > On Tue, Jul 21, 2009 at 12:36 PM, Sergey Beryozkin <
> > sergey.beryozkin@iona.com> wrote:
> >
> >>
> >> Hi
> >>
> >> OK, it's done now on the trunk/2.2.3-SNAPSHOT. Hopefully a 2.2.3 release
> >> will be done next week.
> >> You'd just need to explicitly register JAXBElementProvider and set a
> list
> >> property with a list of class names whose instances need to be wrapped
> >> prior
> >> to serialization, here's a fragment :
> >>
> >> <beans  xmlns:util="http://www.springframework.org/schema/util"
> >>  xsi:schemaLocation="http://www.springframework.org/schema/beans
> >> http://www.springframework.org/schema/beans/spring-beans.xsd
> >> http://www.springframework.org/schema/util
> >> http://www.springframework.org/schema/util/spring-util-2.0.xsd ...">
> >>
> >> <util:list id="jaxbElementClassNames">
> >> <value>org.apache.cxf.systest.jaxrs.BaseType</value>
> >> </util:list>
> >>
> >> <jaxrs:server>
> >>  <jaxrs:providers>
> >>      <ref bean="jaxbProvider"/>
> >>  <jaxrs:providers>
> >> </jaxrs:server>
> >>
> >> <bean id="jaxbProvider"
> >> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
> >> <property name="jaxbElementClassNames" ref="jaxbElementClassNames"/>
> >> </bean>
> >> </beans>
> >>
> >> In meantime, till the release is done, you can register a response JAXRS
> >> filter and wrap the BaseType instance in JAXBElement, it is a bit hacky,
> >> but
> >> you can do something like
> >>
> >> public class JAXBElementWrapper implements ResponseHandler {
> >>    private final static Method m;
> >>    static {
> >>       m = SomeClass.getMethod("get", new Class[0]);
> >>    }
> >>
> >>
> >>    public Response handleResponse(Message m, OperationResourceInfo ori,
> >> Response response) {
> >>
> >>        if (BaseType.class == ori.getMethodToInvoke().getReturnType()) {
> >>            // this is a hacky bit
> >>            OperationResourceInfo ori2 = new OperationResourceInfo(m,
> >> ori.getAnnotatedMethod(), ori.getClassResourceInfo());
> >>            message.getExchange().put(OperationResourceInfo.class, ori2);
> >>            Object instance =
> >> MessageContentsList.getContentsList(message).get(0);
> >>            // convert as Wolfgang suggested or check JAXBElementProvider
> >> source
> >>            JAXBElement el = convertToJAXBElement(instance);
> >>            message.setContent(new MessageContentsList(el));
> >>        }
> >>        return null;
> >>    }
> >>
> >>    private static class SomeClass {
> >>        public JAXBElement<BaseType> get();
> >>    }
> >> }
> >>
> >>
> >> Also, Wolfgang suggested some additional schema updates - not sure if it
> >> will work for you
> >>
> >> thanks, Sergey
> >>
> >>
> >> Qzpmwo wrote:
> >> >
> >> > Hi,
> >> >
> >> > I'm having a strange problem with CXF RESTful service marsahlling base
> >> and
> >> > derived xsd types.
> >> >
> >> > XSD:
> >> >
> >> > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
> >> >     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
> >> >     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
> >> >     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService
> "
> >> >     elementFormDefault="unqualified" jaxb:version="2.0">
> >> >
> >> >    <xs:complexType name="BaseType">
> >> >       <xs:sequence>
> >> >       </xs:sequence>
> >> >    </xs:complexType>
> >> >
> >> >    <xs:complexType name="DerivedType">
> >> >       <xs:complexContent>
> >> >          <xs:extension base="BaseType">
> >> >             <xs:sequence>
> >> >             </xs:sequence>
> >> >          </xs:extension>
> >> >      </xs:complexContent>
> >> >    </xs:complexType>
> >> >
> >> >    <xs:complexType name="ListType">
> >> >       <xs:sequence>
> >> >                <xs:element name="item" type="BaseType" minOccurs="0"
> >> > maxOccurs="unbounded" />
> >> >       </xs:sequence>
> >> >    </xs:complexType>
> >> >
> >> >    <xs:element name="base" type="BaseType" />
> >> >    <xs:element name="derived" type="DerivedType" />
> >> >    <xs:element name="list" type="ListType" />
> >> >
> >> > </xs:schema>
> >> >
> >> > xjc has been used to jenerate java code from xsd. After that:
> >> >
> >> > 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
> >> > annotations have been added to BaseType java class code
> >> > 2) @XmlRootElement has been added to DerivedType java class code
> >> > 3) @XmlRootElement has been added to ListType java class code
> >> >
> >> > When my CXF rest service returns list of the Derived objects it
> >> produces
> >> > xml
> >> > correctly:
> >> >
> >> > <list>
> >> >     <base xsi:type="DerivedType">...</base>
> >> >     ...
> >> >     <base xsi:type="DerivedType">...</base>
> >> > </list>
> >> >
> >> > But when I'm requesting 1 instance of the Derived object XML is wrong
> >> (as
> >> > I
> >> > understand)
> >> >
> >> > <derived>...</derived>
> >> >
> >> > Since I did not specify substitution group in my opinion xml should be
> >> > like
> >> > in list:
> >> >
> >> > <base xsi:type="DerivedType">...</base>
> >> >
> >> > Could you please clarify the issue for me and may be help me to solve
> >> this
> >> > problem.
> >> >
> >> > Forgot to mention that I'm using CXF 2.2
> >> >
> >> > Thanks in advance
> >> > --- Karen
> >> >
> >> >
> >>
> >> --
> >> View this message in context:
> >>
> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24591197.html
> >> Sent from the cxf-user mailing list archive at Nabble.com.
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24593397.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>
>

Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi,

No problems and thanks for raising this issue on this list -  I reckon we've
ended up adding a pretty useful feature (optional JAXBElement wrapping) to
the default JAXBElementProvider wich can be generally useful.

By the way, that workaround I mentioned is a bit hacky though doable - but a
simpler workaround would be to create a custom JAXBElementProvider which
extends the default one and overrides 

protected void marshal(Object obj, Class<?> cls, Type genericType, 
                           String enc, OutputStream os, MediaType mt)

the way it's done currently on the trunk, perhaps explicitly checking for
BaseType


cheers, Sergey 

Qzpmwo wrote:
> 
> Hi Sergey,
> 
> I'm really impressed with your help!
> 
> Thanks a lot
> --- Alex
> 
> On Tue, Jul 21, 2009 at 12:36 PM, Sergey Beryozkin <
> sergey.beryozkin@iona.com> wrote:
> 
>>
>> Hi
>>
>> OK, it's done now on the trunk/2.2.3-SNAPSHOT. Hopefully a 2.2.3 release
>> will be done next week.
>> You'd just need to explicitly register JAXBElementProvider and set a list
>> property with a list of class names whose instances need to be wrapped
>> prior
>> to serialization, here's a fragment :
>>
>> <beans  xmlns:util="http://www.springframework.org/schema/util"
>>  xsi:schemaLocation="http://www.springframework.org/schema/beans
>> http://www.springframework.org/schema/beans/spring-beans.xsd
>> http://www.springframework.org/schema/util
>> http://www.springframework.org/schema/util/spring-util-2.0.xsd ...">
>>
>> <util:list id="jaxbElementClassNames">
>> <value>org.apache.cxf.systest.jaxrs.BaseType</value>
>> </util:list>
>>
>> <jaxrs:server>
>>  <jaxrs:providers>
>>      <ref bean="jaxbProvider"/>
>>  <jaxrs:providers>
>> </jaxrs:server>
>>
>> <bean id="jaxbProvider"
>> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
>> <property name="jaxbElementClassNames" ref="jaxbElementClassNames"/>
>> </bean>
>> </beans>
>>
>> In meantime, till the release is done, you can register a response JAXRS
>> filter and wrap the BaseType instance in JAXBElement, it is a bit hacky,
>> but
>> you can do something like
>>
>> public class JAXBElementWrapper implements ResponseHandler {
>>    private final static Method m;
>>    static {
>>       m = SomeClass.getMethod("get", new Class[0]);
>>    }
>>
>>
>>    public Response handleResponse(Message m, OperationResourceInfo ori,
>> Response response) {
>>
>>        if (BaseType.class == ori.getMethodToInvoke().getReturnType()) {
>>            // this is a hacky bit
>>            OperationResourceInfo ori2 = new OperationResourceInfo(m,
>> ori.getAnnotatedMethod(), ori.getClassResourceInfo());
>>            message.getExchange().put(OperationResourceInfo.class, ori2);
>>            Object instance =
>> MessageContentsList.getContentsList(message).get(0);
>>            // convert as Wolfgang suggested or check JAXBElementProvider
>> source
>>            JAXBElement el = convertToJAXBElement(instance);
>>            message.setContent(new MessageContentsList(el));
>>        }
>>        return null;
>>    }
>>
>>    private static class SomeClass {
>>        public JAXBElement<BaseType> get();
>>    }
>> }
>>
>>
>> Also, Wolfgang suggested some additional schema updates - not sure if it
>> will work for you
>>
>> thanks, Sergey
>>
>>
>> Qzpmwo wrote:
>> >
>> > Hi,
>> >
>> > I'm having a strange problem with CXF RESTful service marsahlling base
>> and
>> > derived xsd types.
>> >
>> > XSD:
>> >
>> > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>> >     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>> >     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>> >     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>> >     elementFormDefault="unqualified" jaxb:version="2.0">
>> >
>> >    <xs:complexType name="BaseType">
>> >       <xs:sequence>
>> >       </xs:sequence>
>> >    </xs:complexType>
>> >
>> >    <xs:complexType name="DerivedType">
>> >       <xs:complexContent>
>> >          <xs:extension base="BaseType">
>> >             <xs:sequence>
>> >             </xs:sequence>
>> >          </xs:extension>
>> >      </xs:complexContent>
>> >    </xs:complexType>
>> >
>> >    <xs:complexType name="ListType">
>> >       <xs:sequence>
>> >                <xs:element name="item" type="BaseType" minOccurs="0"
>> > maxOccurs="unbounded" />
>> >       </xs:sequence>
>> >    </xs:complexType>
>> >
>> >    <xs:element name="base" type="BaseType" />
>> >    <xs:element name="derived" type="DerivedType" />
>> >    <xs:element name="list" type="ListType" />
>> >
>> > </xs:schema>
>> >
>> > xjc has been used to jenerate java code from xsd. After that:
>> >
>> > 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
>> > annotations have been added to BaseType java class code
>> > 2) @XmlRootElement has been added to DerivedType java class code
>> > 3) @XmlRootElement has been added to ListType java class code
>> >
>> > When my CXF rest service returns list of the Derived objects it
>> produces
>> > xml
>> > correctly:
>> >
>> > <list>
>> >     <base xsi:type="DerivedType">...</base>
>> >     ...
>> >     <base xsi:type="DerivedType">...</base>
>> > </list>
>> >
>> > But when I'm requesting 1 instance of the Derived object XML is wrong
>> (as
>> > I
>> > understand)
>> >
>> > <derived>...</derived>
>> >
>> > Since I did not specify substitution group in my opinion xml should be
>> > like
>> > in list:
>> >
>> > <base xsi:type="DerivedType">...</base>
>> >
>> > Could you please clarify the issue for me and may be help me to solve
>> this
>> > problem.
>> >
>> > Forgot to mention that I'm using CXF 2.2
>> >
>> > Thanks in advance
>> > --- Karen
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24591197.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>>
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24593397.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by qzpmwo qzpmwo <qz...@gmail.com>.
Hi Sergey,

I'm really impressed with your help!

Thanks a lot
--- Alex

On Tue, Jul 21, 2009 at 12:36 PM, Sergey Beryozkin <
sergey.beryozkin@iona.com> wrote:

>
> Hi
>
> OK, it's done now on the trunk/2.2.3-SNAPSHOT. Hopefully a 2.2.3 release
> will be done next week.
> You'd just need to explicitly register JAXBElementProvider and set a list
> property with a list of class names whose instances need to be wrapped
> prior
> to serialization, here's a fragment :
>
> <beans  xmlns:util="http://www.springframework.org/schema/util"
>  xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans.xsd
> http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-2.0.xsd ...">
>
> <util:list id="jaxbElementClassNames">
> <value>org.apache.cxf.systest.jaxrs.BaseType</value>
> </util:list>
>
> <jaxrs:server>
>  <jaxrs:providers>
>      <ref bean="jaxbProvider"/>
>  <jaxrs:providers>
> </jaxrs:server>
>
> <bean id="jaxbProvider"
> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
> <property name="jaxbElementClassNames" ref="jaxbElementClassNames"/>
> </bean>
> </beans>
>
> In meantime, till the release is done, you can register a response JAXRS
> filter and wrap the BaseType instance in JAXBElement, it is a bit hacky,
> but
> you can do something like
>
> public class JAXBElementWrapper implements ResponseHandler {
>    private final static Method m;
>    static {
>       m = SomeClass.getMethod("get", new Class[0]);
>    }
>
>
>    public Response handleResponse(Message m, OperationResourceInfo ori,
> Response response) {
>
>        if (BaseType.class == ori.getMethodToInvoke().getReturnType()) {
>            // this is a hacky bit
>            OperationResourceInfo ori2 = new OperationResourceInfo(m,
> ori.getAnnotatedMethod(), ori.getClassResourceInfo());
>            message.getExchange().put(OperationResourceInfo.class, ori2);
>            Object instance =
> MessageContentsList.getContentsList(message).get(0);
>            // convert as Wolfgang suggested or check JAXBElementProvider
> source
>            JAXBElement el = convertToJAXBElement(instance);
>            message.setContent(new MessageContentsList(el));
>        }
>        return null;
>    }
>
>    private static class SomeClass {
>        public JAXBElement<BaseType> get();
>    }
> }
>
>
> Also, Wolfgang suggested some additional schema updates - not sure if it
> will work for you
>
> thanks, Sergey
>
>
> Qzpmwo wrote:
> >
> > Hi,
> >
> > I'm having a strange problem with CXF RESTful service marsahlling base
> and
> > derived xsd types.
> >
> > XSD:
> >
> > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
> >     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
> >     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
> >     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
> >     elementFormDefault="unqualified" jaxb:version="2.0">
> >
> >    <xs:complexType name="BaseType">
> >       <xs:sequence>
> >       </xs:sequence>
> >    </xs:complexType>
> >
> >    <xs:complexType name="DerivedType">
> >       <xs:complexContent>
> >          <xs:extension base="BaseType">
> >             <xs:sequence>
> >             </xs:sequence>
> >          </xs:extension>
> >      </xs:complexContent>
> >    </xs:complexType>
> >
> >    <xs:complexType name="ListType">
> >       <xs:sequence>
> >                <xs:element name="item" type="BaseType" minOccurs="0"
> > maxOccurs="unbounded" />
> >       </xs:sequence>
> >    </xs:complexType>
> >
> >    <xs:element name="base" type="BaseType" />
> >    <xs:element name="derived" type="DerivedType" />
> >    <xs:element name="list" type="ListType" />
> >
> > </xs:schema>
> >
> > xjc has been used to jenerate java code from xsd. After that:
> >
> > 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
> > annotations have been added to BaseType java class code
> > 2) @XmlRootElement has been added to DerivedType java class code
> > 3) @XmlRootElement has been added to ListType java class code
> >
> > When my CXF rest service returns list of the Derived objects it produces
> > xml
> > correctly:
> >
> > <list>
> >     <base xsi:type="DerivedType">...</base>
> >     ...
> >     <base xsi:type="DerivedType">...</base>
> > </list>
> >
> > But when I'm requesting 1 instance of the Derived object XML is wrong (as
> > I
> > understand)
> >
> > <derived>...</derived>
> >
> > Since I did not specify substitution group in my opinion xml should be
> > like
> > in list:
> >
> > <base xsi:type="DerivedType">...</base>
> >
> > Could you please clarify the issue for me and may be help me to solve
> this
> > problem.
> >
> > Forgot to mention that I'm using CXF 2.2
> >
> > Thanks in advance
> > --- Karen
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24591197.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>
>

Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi

OK, it's done now on the trunk/2.2.3-SNAPSHOT. Hopefully a 2.2.3 release
will be done next week.
You'd just need to explicitly register JAXBElementProvider and set a list
property with a list of class names whose instances need to be wrapped prior
to serialization, here's a fragment :

<beans  xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util-2.0.xsd ...">

<util:list id="jaxbElementClassNames">
<value>org.apache.cxf.systest.jaxrs.BaseType</value>
</util:list>

<jaxrs:server>
  <jaxrs:providers>
      <ref bean="jaxbProvider"/>
  <jaxrs:providers>
</jaxrs:server>

<bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="jaxbElementClassNames" ref="jaxbElementClassNames"/>
</bean>
</beans>

In meantime, till the release is done, you can register a response JAXRS
filter and wrap the BaseType instance in JAXBElement, it is a bit hacky, but
you can do something like

public class JAXBElementWrapper implements ResponseHandler {
    private final static Method m;
    static {
       m = SomeClass.getMethod("get", new Class[0]);
    }


    public Response handleResponse(Message m, OperationResourceInfo ori,
Response response) {
        
        if (BaseType.class == ori.getMethodToInvoke().getReturnType()) {
            // this is a hacky bit
            OperationResourceInfo ori2 = new OperationResourceInfo(m,
ori.getAnnotatedMethod(), ori.getClassResourceInfo());
            message.getExchange().put(OperationResourceInfo.class, ori2);
            Object instance =
MessageContentsList.getContentsList(message).get(0);
            // convert as Wolfgang suggested or check JAXBElementProvider
source
            JAXBElement el = convertToJAXBElement(instance);
            message.setContent(new MessageContentsList(el));
        }
        return null;
    }

    private static class SomeClass {
        public JAXBElement<BaseType> get();
    }
}


Also, Wolfgang suggested some additional schema updates - not sure if it
will work for you

thanks, Sergey


Qzpmwo wrote:
> 
> Hi,
> 
> I'm having a strange problem with CXF RESTful service marsahlling base and
> derived xsd types.
> 
> XSD:
> 
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     elementFormDefault="unqualified" jaxb:version="2.0">
> 
>    <xs:complexType name="BaseType">
>       <xs:sequence>
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:complexType name="DerivedType">
>       <xs:complexContent>
>          <xs:extension base="BaseType">
>             <xs:sequence>
>             </xs:sequence>
>          </xs:extension>
>      </xs:complexContent>
>    </xs:complexType>
> 
>    <xs:complexType name="ListType">
>       <xs:sequence>
>                <xs:element name="item" type="BaseType" minOccurs="0"
> maxOccurs="unbounded" />
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:element name="base" type="BaseType" />
>    <xs:element name="derived" type="DerivedType" />
>    <xs:element name="list" type="ListType" />
> 
> </xs:schema>
> 
> xjc has been used to jenerate java code from xsd. After that:
> 
> 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
> annotations have been added to BaseType java class code
> 2) @XmlRootElement has been added to DerivedType java class code
> 3) @XmlRootElement has been added to ListType java class code
> 
> When my CXF rest service returns list of the Derived objects it produces
> xml
> correctly:
> 
> <list>
>     <base xsi:type="DerivedType">...</base>
>     ...
>     <base xsi:type="DerivedType">...</base>
> </list>
> 
> But when I'm requesting 1 instance of the Derived object XML is wrong (as
> I
> understand)
> 
> <derived>...</derived>
> 
> Since I did not specify substitution group in my opinion xml should be
> like
> in list:
> 
> <base xsi:type="DerivedType">...</base>
> 
> Could you please clarify the issue for me and may be help me to solve this
> problem.
> 
> Forgot to mention that I'm using CXF 2.2
> 
> Thanks in advance
> --- Karen
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24591197.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by qzpmwo qzpmwo <qz...@gmail.com>.
Hi Sergey,

Thanks a lot.

--- Karen

On Tue, Jul 21, 2009 at 8:12 AM, Sergey Beryozkin <sergey.beryozkin@iona.com
> wrote:

>
> Hi
>
> I can see that Wolfgang Laun actually replied, but it appears that he sees
> the output being correct.
> I have asked for some additional clarifications, but in meantime, if you do
> need that specific output being produced, then we might be able to extend
> JAXBElementProvider to wrap certain types into JAXBElements which will
> result in the output you need. Lets see what Wolfgang replies and if says
> 'not possible' then I'll give it a try
>
> Cheers, Sergey
>
>
>
> Sergey Beryozkin wrote:
> >
> > Hi,
> >
> > Thanks for posting it. Actually, you'll likely get a faster response if
> > you ask on the jaxb-users list, as opposed to jaxb-dev. If you do post to
> > the users as well, then please consider dropping my response as it makes
> > it a bit more difficult for JAXB experts out there to see what the real
> > issue is, just ask them what is the way to force JAXB to introduce
> > xsi:type into a serialized XML fragment for DerivedType, given the
> > original schema
> >
> > cheers, Sergey
> >
> >
> >
> > Qzpmwo wrote:
> >>
> >> Hi Sergey,
> >>
> >> Thanks a lot for so fast response and your investigation. I have posted
> >> my initial email and your response to jaxb nabble.
> >>
> >>
> >>
> >>
> >> Sergey Beryozkin wrote:
> >>>
> >>> Hi
> >>>
> >>> I've experimented a bit and I've managed to have a test producing the
> >>> expected data, but only when using an explicit JAXBElement, this one
> >>>
> >>> @Test
> >>> public void testWriteDerivedTypeJaxbElement() throws Exception {
> >>>         JAXBElementProvider provider = new JAXBElementProvider();
> >>>         Method m = CollectionsResource.class.getMethod("getBaseJaxb",
> >>> new Class[0]);
> >>>         DerivedType derived = new DerivedType();
> >>>         JAXBElement<BaseType> jaxb = new
> >>> JAXBElement<BaseType>(_Base_QNAME, BaseType.class, null, derived);
> >>>         ByteArrayOutputStream bos = new ByteArrayOutputStream();
> >>>         provider.writeTo(jaxb, m.getReturnType(),
> >>> m.getGenericReturnType(),
> >>>                        new Annotation[0], MediaType.TEXT_XML_TYPE, new
> >>> MetadataMap<String, Object>(), bos);
> >>>         String s = bos.toString();
> >>>         System.out.println(s);
> >>>
> >>> }
> >>>
> >>> produces
> >>>
> >>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:base
> >>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"
> >>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> >>> xsi:type="ns2:DerivedType"/>
> >>>
> >>> I'm presuming you have a method like this one :
> >>>
> >>>
> >>> public class RootResource {
> >>>   @GET
> >>>   public BaseType getType() { return new DerivedType(); }
> >>> }
> >>>
> >>> I'm not sure why JAXB chooses to serialize it as
> >>>
> >>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:derivedType
> >>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"/>
> >>>
> >>> in this case, given that ObjectFactory has a method returning
> >>> JAXBElement<BaseType>. I tried to force an ObjectFactory method
> >>> returning JAXBElement<BaseType> be used, I removed @XmlRootElement on
> >>> BaseType but it didn't make any difference. Removing @XmlRootElement on
> >>> DerivedType causes a JAXB failure - though ObjectFactory has a method
> >>> returning JAXBElement<DerivedType>.
> >>>
> >>> Can you please post a question to the JAXB users list ? I'd be
> >>> interested to see what they reply. Unless our resident experts (Dan,
> >>> Benson) can help ?
> >>>
> >>> thanks, Sergey
> >>>
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24586518.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>
>

Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi

I can see that Wolfgang Laun actually replied, but it appears that he sees
the output being correct.
I have asked for some additional clarifications, but in meantime, if you do
need that specific output being produced, then we might be able to extend
JAXBElementProvider to wrap certain types into JAXBElements which will
result in the output you need. Lets see what Wolfgang replies and if says
'not possible' then I'll give it a try

Cheers, Sergey 
 


Sergey Beryozkin wrote:
> 
> Hi,
> 
> Thanks for posting it. Actually, you'll likely get a faster response if
> you ask on the jaxb-users list, as opposed to jaxb-dev. If you do post to
> the users as well, then please consider dropping my response as it makes
> it a bit more difficult for JAXB experts out there to see what the real
> issue is, just ask them what is the way to force JAXB to introduce
> xsi:type into a serialized XML fragment for DerivedType, given the
> original schema
> 
> cheers, Sergey
> 
> 
> 
> Qzpmwo wrote:
>> 
>> Hi Sergey,
>> 
>> Thanks a lot for so fast response and your investigation. I have posted
>> my initial email and your response to jaxb nabble.
>> 
>> 
>> 
>> 
>> Sergey Beryozkin wrote:
>>> 
>>> Hi
>>> 
>>> I've experimented a bit and I've managed to have a test producing the
>>> expected data, but only when using an explicit JAXBElement, this one 
>>> 
>>> @Test
>>> public void testWriteDerivedTypeJaxbElement() throws Exception {
>>>         JAXBElementProvider provider = new JAXBElementProvider();
>>>         Method m = CollectionsResource.class.getMethod("getBaseJaxb",
>>> new Class[0]);
>>>         DerivedType derived = new DerivedType();
>>>         JAXBElement<BaseType> jaxb = new
>>> JAXBElement<BaseType>(_Base_QNAME, BaseType.class, null, derived); 
>>>         ByteArrayOutputStream bos = new ByteArrayOutputStream();
>>>         provider.writeTo(jaxb, m.getReturnType(),
>>> m.getGenericReturnType(),
>>>                        new Annotation[0], MediaType.TEXT_XML_TYPE, new
>>> MetadataMap<String, Object>(), bos);
>>>         String s = bos.toString();
>>>         System.out.println(s);
>>>         
>>> }
>>> 
>>> produces
>>> 
>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:base
>>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>> xsi:type="ns2:DerivedType"/>
>>> 
>>> I'm presuming you have a method like this one :
>>> 
>>> 
>>> public class RootResource {
>>>   @GET
>>>   public BaseType getType() { return new DerivedType(); }
>>> }
>>> 
>>> I'm not sure why JAXB chooses to serialize it as
>>> 
>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:derivedType
>>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"/>
>>> 
>>> in this case, given that ObjectFactory has a method returning
>>> JAXBElement<BaseType>. I tried to force an ObjectFactory method
>>> returning JAXBElement<BaseType> be used, I removed @XmlRootElement on
>>> BaseType but it didn't make any difference. Removing @XmlRootElement on
>>> DerivedType causes a JAXB failure - though ObjectFactory has a method
>>> returning JAXBElement<DerivedType>.
>>> 
>>> Can you please post a question to the JAXB users list ? I'd be
>>> interested to see what they reply. Unless our resident experts (Dan,
>>> Benson) can help ?
>>> 
>>> thanks, Sergey
>>> 
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24586518.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi,

Thanks for posting it. Actually, you'll likely get a faster response if you
ask on the jaxb-users list, as opposed to jaxb-dev. If you do post to the
users as well, then please consider dropping my response as it makes it a
bit more difficult for JAXB experts out there to see what the real issue is,
just ask them what is the way to force JAXB to introduce xsi:type into a
serialized XML fragment for DerivedType, given the original schema

cheers, Sergey



Qzpmwo wrote:
> 
> Hi Sergey,
> 
> Thanks a lot for so fast response and your investigation. I have posted my
> initial email and your response to jaxb nabble.
> 
> 
> 
> 
> Sergey Beryozkin wrote:
>> 
>> Hi
>> 
>> I've experimented a bit and I've managed to have a test producing the
>> expected data, but only when using an explicit JAXBElement, this one 
>> 
>> @Test
>> public void testWriteDerivedTypeJaxbElement() throws Exception {
>>         JAXBElementProvider provider = new JAXBElementProvider();
>>         Method m = CollectionsResource.class.getMethod("getBaseJaxb", new
>> Class[0]);
>>         DerivedType derived = new DerivedType();
>>         JAXBElement<BaseType> jaxb = new
>> JAXBElement<BaseType>(_Base_QNAME, BaseType.class, null, derived); 
>>         ByteArrayOutputStream bos = new ByteArrayOutputStream();
>>         provider.writeTo(jaxb, m.getReturnType(),
>> m.getGenericReturnType(),
>>                        new Annotation[0], MediaType.TEXT_XML_TYPE, new
>> MetadataMap<String, Object>(), bos);
>>         String s = bos.toString();
>>         System.out.println(s);
>>         
>> }
>> 
>> produces
>> 
>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:base
>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> xsi:type="ns2:DerivedType"/>
>> 
>> I'm presuming you have a method like this one :
>> 
>> 
>> public class RootResource {
>>   @GET
>>   public BaseType getType() { return new DerivedType(); }
>> }
>> 
>> I'm not sure why JAXB chooses to serialize it as
>> 
>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:derivedType
>> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"/>
>> 
>> in this case, given that ObjectFactory has a method returning
>> JAXBElement<BaseType>. I tried to force an ObjectFactory method returning
>> JAXBElement<BaseType> be used, I removed @XmlRootElement on BaseType but
>> it didn't make any difference. Removing @XmlRootElement on DerivedType
>> causes a JAXB failure - though ObjectFactory has a method returning
>> JAXBElement<DerivedType>.
>> 
>> Can you please post a question to the JAXB users list ? I'd be interested
>> to see what they reply. Unless our resident experts (Dan, Benson) can
>> help ?
>> 
>> thanks, Sergey
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24571272.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by Qzpmwo <qz...@gmail.com>.
Hi Sergey,

Thanks a lot for so fast response and your investigation. I have posted my
initial email and your response to jaxb nabble.




Sergey Beryozkin wrote:
> 
> Hi
> 
> I've experimented a bit and I've managed to have a test producing the
> expected data, but only when using an explicit JAXBElement, this one 
> 
> @Test
> public void testWriteDerivedTypeJaxbElement() throws Exception {
>         JAXBElementProvider provider = new JAXBElementProvider();
>         Method m = CollectionsResource.class.getMethod("getBaseJaxb", new
> Class[0]);
>         DerivedType derived = new DerivedType();
>         JAXBElement<BaseType> jaxb = new
> JAXBElement<BaseType>(_Base_QNAME, BaseType.class, null, derived); 
>         ByteArrayOutputStream bos = new ByteArrayOutputStream();
>         provider.writeTo(jaxb, m.getReturnType(),
> m.getGenericReturnType(),
>                        new Annotation[0], MediaType.TEXT_XML_TYPE, new
> MetadataMap<String, Object>(), bos);
>         String s = bos.toString();
>         System.out.println(s);
>         
> }
> 
> produces
> 
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:base
> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:type="ns2:DerivedType"/>
> 
> I'm presuming you have a method like this one :
> 
> 
> public class RootResource {
>   @GET
>   public BaseType getType() { return new DerivedType(); }
> }
> 
> I'm not sure why JAXB chooses to serialize it as
> 
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:derivedType
> xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"/>
> 
> in this case, given that ObjectFactory has a method returning
> JAXBElement<BaseType>. I tried to force an ObjectFactory method returning
> JAXBElement<BaseType> be used, I removed @XmlRootElement on BaseType but
> it didn't make any difference. Removing @XmlRootElement on DerivedType
> causes a JAXB failure - though ObjectFactory has a method returning
> JAXBElement<DerivedType>.
> 
> Can you please post a question to the JAXB users list ? I'd be interested
> to see what they reply. Unless our resident experts (Dan, Benson) can help
> ?
> 
> thanks, Sergey
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24570653.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi

I'm presuming you have a method like this one :

I've experimented a bit and I've managed to have a test producing the
expected data, but only when using an explicit JAXBElement, this one 

@Test
public void testWriteDerivedTypeJaxbElement() throws Exception {
        JAXBElementProvider provider = new JAXBElementProvider();
        Method m = CollectionsResource.class.getMethod("getBaseJaxb", new
Class[0]);
        DerivedType derived = new DerivedType();
        JAXBElement<BaseType> jaxb = new JAXBElement<BaseType>(_Base_QNAME,
BaseType.class, null, derived); 
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        provider.writeTo(jaxb, m.getReturnType(), m.getGenericReturnType(),
                       new Annotation[0], MediaType.TEXT_XML_TYPE, new
MetadataMap<String, Object>(), bos);
        String s = bos.toString();
        System.out.println(s);
        
}

produces

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:base
xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="ns2:DerivedType"/>

public class RootResource {
  @GET
  public BaseType getType() { return new DerivedType(); }
}

I'm not sure why JAXB chooses to serialize it as

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:derivedType
xmlns:ns2="http://www.cisco.com/dms/xml/ns/dsmCommonService"/>

in this case, given that ObjectFactory has a method returning
JAXBElement<BaseType>. I tried to force an ObjectFactory method returning
JAXBElement<BaseType> be used, I removed @XmlRootElement on BaseType but it
didn't make any difference. Removing @XmlRootElement on DerivedType causes a
JAXB failure - though ObjectFactory has a method returning
JAXBElement<DerivedType>.

Can you please post a question to the JAXB users list ? I'd be interested to
see what they reply. Unless our resident experts (Dan, Benson) can help ?

thanks, Sergey








qzpmwo qzpmwo wrote:
> 
> Hi,
> 
> I'm having a strange problem with CXF RESTful service marsahlling base and
> derived xsd types.
> 
> XSD:
> 
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     elementFormDefault="unqualified" jaxb:version="2.0">
> 
>    <xs:complexType name="BaseType">
>       <xs:sequence>
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:complexType name="DerivedType">
>       <xs:complexContent>
>          <xs:extension base="BaseType">
>             <xs:sequence>
>             </xs:sequence>
>          </xs:extension>
>      </xs:complexContent>
>    </xs:complexType>
> 
>    <xs:complexType name="ListType">
>       <xs:sequence>
>                <xs:element name="item" type="BaseType" minOccurs="0"
> maxOccurs="unbounded" />
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:element name="base" type="BaseType" />
>    <xs:element name="derived" type="DerivedType" />
>    <xs:element name="list" type="ListType" />
> 
> </xs:schema>
> 
> xjc has been used to jenerate java code from xsd. After that:
> 
> 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
> annotations have been added to BaseType java class code
> 2) @XmlRootElement has been added to DerivedType java class code
> 3) @XmlRootElement has been added to ListType java class code
> 
> When my CXF rest service returns list of the Derived objects it produces
> xml
> correctly:
> 
> <list>
>     <base xsi:type="DerivedType">...</base>
>     ...
>     <base xsi:type="DerivedType">...</base>
> </list>
> 
> But when I'm requesting 1 instance of the Derived object XML is wrong (as
> I
> understand)
> 
> <derived>...</derived>
> 
> Since I did not specify substitution group in my opinion xml should be
> like
> in list:
> 
> <base xsi:type="DerivedType">...</base>
> 
> Could you please clarify the issue for me and may be help me to solve this
> problem.
> 
> Forgot to mention that I'm using CXF 2.2
> 
> Thanks in advance
> --- Karen
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24568009.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Possible problem with JAXB marshalling

Posted by Sergey Beryozkin <se...@iona.com>.
Hi - I'll investigate it on Monday and get back to you asap
it might be we're not handling @XmlSeeAlso properly

thanks, Sergey


qzpmwo qzpmwo wrote:
> 
> Hi,
> 
> I'm having a strange problem with CXF RESTful service marsahlling base and
> derived xsd types.
> 
> XSD:
> 
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>     xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>     xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>     elementFormDefault="unqualified" jaxb:version="2.0">
> 
>    <xs:complexType name="BaseType">
>       <xs:sequence>
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:complexType name="DerivedType">
>       <xs:complexContent>
>          <xs:extension base="BaseType">
>             <xs:sequence>
>             </xs:sequence>
>          </xs:extension>
>      </xs:complexContent>
>    </xs:complexType>
> 
>    <xs:complexType name="ListType">
>       <xs:sequence>
>                <xs:element name="item" type="BaseType" minOccurs="0"
> maxOccurs="unbounded" />
>       </xs:sequence>
>    </xs:complexType>
> 
>    <xs:element name="base" type="BaseType" />
>    <xs:element name="derived" type="DerivedType" />
>    <xs:element name="list" type="ListType" />
> 
> </xs:schema>
> 
> xjc has been used to jenerate java code from xsd. After that:
> 
> 1)  @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
> annotations have been added to BaseType java class code
> 2) @XmlRootElement has been added to DerivedType java class code
> 3) @XmlRootElement has been added to ListType java class code
> 
> When my CXF rest service returns list of the Derived objects it produces
> xml
> correctly:
> 
> <list>
>     <base xsi:type="DerivedType">...</base>
>     ...
>     <base xsi:type="DerivedType">...</base>
> </list>
> 
> But when I'm requesting 1 instance of the Derived object XML is wrong (as
> I
> understand)
> 
> <derived>...</derived>
> 
> Since I did not specify substitution group in my opinion xml should be
> like
> in list:
> 
> <base xsi:type="DerivedType">...</base>
> 
> Could you please clarify the issue for me and may be help me to solve this
> problem.
> 
> Forgot to mention that I'm using CXF 2.2
> 
> Thanks in advance
> --- Karen
> 
> 

-- 
View this message in context: http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24550333.html
Sent from the cxf-user mailing list archive at Nabble.com.