users@jaxb.java.net

Re: [jaxb-20-comments] cannot adapt an XmlRootElement ?

From: Mark Hansen <mark_at_javector.com>
Date: Sat, 21 Jan 2006 12:38:42 -0500

OK - thanks. I entered that bug report (#117). Do you have any idea
when the 2.0 spec will be finalized?

Sekhar Vajjhala wrote:

> mark_at_javector.com wrote:
>
>> Thank you for the detailed explanation. I do not think the Sun RI
>> implements
>> either the marshalling or the unmarshalling case. Details below.
>> Should I
>> enter this as a bug report?
>
>
> Sorry for my delayed reply.
>
> There is already a bug report:
> https://jaxb.dev.java.net/issues/show_bug.cgi?id=117
> which seems to contain the text below.
>
>
>>
>> The following code example should work. However, can you confirm
>> thatI need the
>> @XmlJavaTypeAdapter on *both* the value-type class (so the
>> unmarshaller knows
>> what to do) and the bound-type class (so the marshaller knows what do
>> to)?
>> Value-Type = Foo
>> Bound-Type = MyFoo
>>
>> @XmlRootElement
>> @XmlJavaTypeAdapter(MyFooAdapter.class)
>> public class Foo {
>
>
> The annotation is not correct. MyFooAdapter adapts
> MyFoo -> Foo but what you are trying to do is
> adapt Foo->MyFoo. This requires a new annotation.
> Furthermore, it might be desirable to ensure that this solution
> works well when the use cases involve interfaces as opposed
> to concrete classes.
>
> So we will address this in a future version of the spec.
> We will use the defect report 117 to track this request.
> For now, as Kohsuke suggested, you can invoke the adapter
> yourself.
>
> Thanks for bringing up the issue.
>
> regards
> Sekhar Vajjhala
>
>>
>>
>> String x;
>>
>> }
>>
>> @XmlJavaTypeAdapter(MyFooAdapter.class)
>> public class MyFoo {
>>
>> String y;
>>
>> }
>>
>> public class MyFooAdapter extends XmlAdapter<Foo, MyFoo> { ... }
>>
>> Then, this marshalling / unmarshalling should work:
>>
>> MyFoo myFoo = new MyFoo();
>> myFoo.y = "Hello World";
>> m.marshal(myFoo, System.out)
>>
>> should print a serializer instance of Foo like this:
>>
>> <foo><x>Hello World</x></foo>
>>
>> And if I do this:
>>
>> MyFoo myFoo = u.unmarshal(
>> new StringReader("<foo><x>Hello World</x></foo>");
>>
>> That should work also - right?
>>
>> But with the Sun RI, I get the following errors:
>>
>> Marshalling ...
>> [java] javax.xml.bind.MarshalException
>> [java] - with linked exception:
>> [java] [org.xml.sax.SAXException: unable to marshal type
>> "samples.MyFoo" as
>> an element because it is missing an @XmlRootElement annotation]
>>
>>
>> Unmarshalling ...
>> [java] java.lang.ClassCastException: samples.Foo
>> [java] at samples.MyFooSerializer.main(MyFooSerializer.java:34)
>>
>>
>>
>>
>>
>>
>> Quoting Sekhar Vajjhala <Sekhar.Vajjhala_at_Sun.COM>:
>>
>>> Mark Hansen wrote:
>>>
>>>> It appears that you cannot get JAXB to adapt a root element class.
>>>> So, there is no way to marshal a bound type to a global element.
>>>
>>>
>>>
>>> Thanks for the feedback and interest in JAXB 2.0.
>>>
>>> I agree this case needs to be supported.
>>>
>>> The spec already supports this case but requires a partial
>>> fix. Details below
>>>
>>>>
>>>>
>>>> The spec requires a "point of reference" for the bound type. And
>>>> when the bound type is the root element class, then there is no
>>>> point of reference. This seems like a problem with the specification.
>>>
>>>
>>>
>>> You are correct that there is no "point of reference" in the bound
>>> type, MyFoo i.e. there is no property/field that reference
>>> MyFoo. However, marshalling and unmarshalling is still required to
>>> adapt the class using MyFooAdapter. This is required by the runtime
>>> processing model specified in Appendix B, "Runtime Processing", that
>>> deals with marshalling/unmarshalling of XML instances. Referenced
>>> below are sections from Appendix B which shows the requirements for
>>> the adapter to be used.
>>>
>>> Unmarshalling:
>>> =============
>>>
>>> The use of adapter for unmarshalling is required by section B.3.1,
>>> "Gobally Declared Root Element", page 305 , bullet item b. of the
>>> Proposed Final Draft which contains the following:
>>>
>>> ------- begin excerpt from the JAXB 2.0 spec ---------
>>> b. if a type annotated with @XmlRootElement is found and is not
>>> annotated with @XmlJavaTypeAdapter, then the valueType is type that
>>> has been annotated. For e.g.
>>>
>>> @XmlRootElement(...)
>>> public class Foo { ... }
>>>
>>> The valueType is Foo.
>>>
>>> if a type annotated with @XmlRootElement is found and is annotated
>>> with @XmlJavaTypeAdapter, then the valueType is the type that has
>>> been specified in @XmlJavaTypeAdapter.value().
>>> ------- end excerpt from the JAXB 2.0 spec ---------
>>>
>>> Marshalling:
>>> ============
>>> Marshalling is covered by section, Section B.4,
>>> "Marshalling". Sub section b.4.2.1, "JAXBElement" requires the use of
>>> adapter when a JAXBElement instance is being marshalled. From Bullet
>>> item 6.
>>>
>>> -------- begin excerpt from Appendix B ---------
>>> 6. determine the valueType to be marshalled. If the program element
>>> being processed is associated with @XmlJavaTypeAdapter then
>>> boundType is valueType =
>>> @XmlJavaTypeAdapter.value().marshal(boundType)
>>> otherwise valueType is boundType.
>>> -------- end excerpt from Appendix B ---------
>>>
>>> However, the requirement on the use of an adapter is missing from
>>> section section B.4.2, "Class" when a type annotated with
>>> XmlRootElement is marshalled. This was an omission, which I will
>>> correct.
>>>
>>>>
>>>>
>>>> I.e., you should be able to do this (Foo is the value type and
>>>> MyFoo is the bound type):
>>>>
>>>> @XmlRootElement
>>>> @XmlJavaTypeAdapter(MyFooAdapter.class)
>>>> public class MyFoo {
>>>> ....
>>>> }
>>>>
>>>>
>>>> @XmlRootElement
>>>> public class Foo {
>>>> ....
>>>> }
>>>>
>>>>
>>>> Given the above, when you marshal an instance of MyFoo, it should
>>>> produce the XML that is mapped from Foo. But, the Sun RI does not
>>>> work like this. It seems to ignore the adapter. It seems that
>>>> this behavior is consistent with the specification - since there is
>>>> not "point of reference" for MyFoo in the actual class definition
>>>> of MyFoo. However, the upshot is that you can't marshal a boutn
>>>> type to a global element. That seems like a common use case that
>>>> JAXB 2.0 should handle.
>>>>
>>>> Pleasse let me know if I am missing something.
>>>>
>>>> -- Mark
>>>
>>>
>>>
>>>
>>> regards
>>> Sekhar Vajjhala
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>
>>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>