Hi Farrukh,
On 8.11.2011 19:17, Farrukh Najmi wrote:
> On 11/08/2011 12:36 PM, Jakub Podlesak wrote:
>> Hi Farrukh,
>>
>> I meant to keep the client intact, and update the server to only take
>> the RemoveObjectsRequest entity:
>> public Response putRequest(RemoveObjectsRequest req)
>> the above should work fine.
>
> The problem is that I really need to accept all types of
> RegistryRequestType sub-types in that resource method.
Understood, just wanted to make sure at least the scenario which is
supposed
to work out of the box works fine.
>
>>
>> What might help you to fix the original issue would be to provide a
>> JAXBContext resolver
>> to return a JAXBContext aware of all the JAXB beans involved in your
>> RegistryRequestType hierarchy, i.e something like follows:
>
> I have a JAXBContextResolver that does something similar:
>
> @Provider
> public final class JAXBContextResolver implements
> ContextResolver<JAXBContext> {
>
> private final JAXBContext context;
> private static final Log LOG =
> LogFactory.getLog(JAXBContextResolver.class);
>
> public JAXBContextResolver() throws Exception {
>
> LOG.debug("org.freebxml.omar.server.interfaces.rest.JAXBContextResolver constructor");
>
> this.context = new JSONJAXBContext(
> JSONConfiguration.natural().build(),
> BindingUtility.jaxbContextPath);
> }
>
> public JAXBContext getContext(Class<?> objectType) {
> String pkgName = objectType.getPackage().getName();
> String[] pkgs = BindingUtility.jaxbContextPath.split(":");
> //Get the set of fully-qualified package names for my JAXB context
> classes
> List pkgs2 = Arrays.asList(pkgs);
> boolean found = pkgs2.contains(pkgName);
> LOG.debug("objectType: " + objectType + " found: " + found);
>
> return found ? context : null;
> }
> }
Hmm, that looks fine.
>
> Any other suggestions beside a paired down reproducable test case come
> to mind?
I am sorry, no other suggestions,
~Jakub
>
> Again thanks so very much for your help and being mindful of your
> valuable time I want to restate that this issue is not a high priority
> as there is a workaround.
>
>>
>> @Provider
>> public class JAXBContextResolver implements
>> ContextResolver<JAXBContext> {
>> private JAXBContext context;
>> private final Class[] cTypes = {RegistryRequestType.class,
>> RemoveObjectsRequest.class /* all other classes extending the
>> RegistryRequestType class */ };
>> private final Set<Class> types;
>> public JAXBContextResolver() {
>> try {
>> this.types = new HashSet<Class>(Arrays.asList(cTypes));
>> this.context = JAXBContext.newInstance(cTypes);
>> } catch (JAXBException ex) {
>> throw new RuntimeException(ex);
>> }
>> }
>>
>> @Override
>> public JAXBContext getContext(Class<?> c) {
>> return types.contains(c) ? context : null;
>> }
>> }
>>
>> Does it help?
>>
>> ~Jakub
>>
>>
>> On 8.11.2011 15:38, Farrukh Najmi wrote:
>>>
>>> Hi Jakub,
>>>
>>> I did not understand what you want me to try. The request entity
>>> needs to be a RemoveObjectsRequest element. In my JAXB generated
>>> bindings there are the following classes:
>>>
>>> public class RegistryRequestType {
>>> ...
>>> }
>>>
>>> public class RemoveObjectsRequest extends RegistryRequestType {
>>> ...
>>> }
>>>
>>> In my resource method I expect RegistryRequestType param to have the
>>> specific sub-type of RegistryRequestType (e.g. RemoveObjectsRequest)
>>> based on the element that was in teh request entity.
>>>
>>> With that summary what were you suggesting I try? Also, why is my
>>> assumption on expected behavior incorrect? It seems to make sense
>>> that jersey server should be able to unmarshall a
>>> RemoveObjectsRequest type and pass it as a RegistryRequestType to my
>>> resource method.
>>>
>>> Thank you for your kind help.
>>>
>>> On 11/08/2011 08:31 AM, Jakub Podlesak wrote:
>>>> Possibly. Do you have any chance to try out with the same type,
>>>> ideally just RemoveObjectsRequest?
>>>>
>>>> ~Jakub
>>>>
>>>> On 8.11.2011 13:27, Farrukh Najmi wrote:
>>>>> Hi Jakub,
>>>>>
>>>>> At the beginin of this thread I mentioned that
>>>>> RemoveObjectsRequest extends RegistryRequestType. Therefor I
>>>>> assumed that it was OK to pass a RemoveObjectsRequest where the
>>>>> resource method is expecting a RegistryRequestType. Am I wrong in
>>>>> this assumption?
>>>>>
>>>>> On 11/08/2011 03:44 AM, Jakub Podlesak wrote:
>>>>>> Hi Farrukh,
>>>>>>
>>>>>> please see in lines...
>>>>>>
>>>>>> On 7.11.2011 21:09, Farrukh Najmi wrote:
>>>>>>>
>>>>>>> Hi Jakub,
>>>>>>>
>>>>>>> There does not seem to be any difference whether I do either of
>>>>>>> the following on client side:
>>>>>>>
>>>>>>> RemoveObjectsRequest removeRequest = ...;
>>>>>>
>>>>>> The above removeRequest is of the *RemoveObjectsRequest* type
>>>>>>
>>>>>>> ClientResponse resp =
>>>>>>> webResource.accept(MediaType.APPLICATION_XML).
>>>>>>> type(MediaType.APPLICATION_XML).
>>>>>>> entity(removeRequest).
>>>>>>
>>>>>> and is passed here to the client
>>>>>>
>>>>>>> put(ClientResponse.class);
>>>>>>>
>>>>>>> Or.
>>>>>>>
>>>>>>> ClientResponse resp =
>>>>>>> webResource.accept(MediaType.APPLICATION_XML).
>>>>>>> type(MediaType.APPLICATION_XML).
>>>>>>> entity(BindingUtility.marshalObject(removeRequest)).
>>>>>>> //marshalls RemoveObjectsRequest object to a String
>>>>>>> put(ClientResponse.class);
>>>>>>>
>>>>>>> In both cases if the resource method signature is:
>>>>>>>
>>>>>>> public Response putRequest(RegistryRequestType req)
>>>>>>
>>>>>> while above you are consuming *RegistryRequestType*, you mention
>>>>>> this also in the following line.
>>>>>> My suggestion was to try sending and consuming the very same type.
>>>>>>
>>>>>> ~Jakub
>>>>>>
>>>>>>>
>>>>>>> then I get a RegistryRequestType instance rather than a
>>>>>>> RemoveObjectsRequest instance.
>>>>>>>
>>>>>>> The workaround I did on the server side to change the method
>>>>>>> signature to:
>>>>>>>
>>>>>>> public Response putRequest(String entityStr);
>>>>>>>
>>>>>>> and then unmarshalling from string manually works in both cases.
>>>>>>>
>>>>>>> This is not high priority but I am curious why this does not
>>>>>>> work as expected. Making a reproducable test case is not trivial
>>>>>>> but I would be glad to help debug this further if you think it
>>>>>>> could be an issue that needs filiing and eventual fixing.
>>>>>>>
>>>>>>> Thanks very much for your help.
>>>>>>>
>>>>>>> On 11/07/2011 11:41 AM, Jakub Podlesak wrote:
>>>>>>>> Hi Farrukh,
>>>>>>>>
>>>>>>>> The problem was that on the client side you referred to your
>>>>>>>> own BindingUtility to serialize
>>>>>>>> the XML for you, while on the server side you expected Jersey
>>>>>>>> to automatically
>>>>>>>> pick up whatever the BindingUtility produced.
>>>>>>>>
>>>>>>>> What happens if you directly passed a RegistryRequestType to
>>>>>>>> the web resource entity method on the client side?
>>>>>>>> I presume that should work all right for you...
>>>>>>>>
>>>>>>>> ~Jakub
>>>>>>>>
>>>>>>>>
>>>>>>>> On 7.11.2011 16:15, Farrukh Najmi wrote:
>>>>>>>>> On 11/07/2011 09:18 AM, Farrukh Najmi wrote:
>>>>>>>>>> Hi Guys,
>>>>>>>>>>
>>>>>>>>>> I have an XML Schema as follows:
>>>>>>>>>>
>>>>>>>>>> <complexType name="RegistryRequestType">
>>>>>>>>>> ...
>>>>>>>>>> </complexType>
>>>>>>>>>>
>>>>>>>>>> <element name="RemoveObjectsRequest">
>>>>>>>>>> <complexType>
>>>>>>>>>> <complexContent>
>>>>>>>>>> <extension base="rs:RegistryRequestType">
>>>>>>>>>> ....
>>>>>>>>>> </extension>
>>>>>>>>>> </complexContent>
>>>>>>>>>> </complexType>
>>>>>>>>>>
>>>>>>>>>> I use JAXB to generate bindings for above schema as follows:
>>>>>>>>>>
>>>>>>>>>> public class RegistryRequestType {
>>>>>>>>>> ...
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> public class RemoveObjectsRequest extends RegistryRequestType {
>>>>>>>>>> ...
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I have a jersey server resource method as follows:
>>>>>>>>>>
>>>>>>>>>> @PUT
>>>>>>>>>> @Consumes({"application/xml"})
>>>>>>>>>> @Produces({"application/xml"})
>>>>>>>>>> @Path("/requests")
>>>>>>>>>> public Response putRequest(RegistryRequestType req) {
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I issue a client PUT request where entity is a
>>>>>>>>>> RemoveObjectsRequest element using following code:
>>>>>>>>>>
>>>>>>>>>> RemoveObjectsRequest removeRequest = ...
>>>>>>>>>> ClientResponse resp =
>>>>>>>>>> webResource.accept(MediaType.APPLICATION_XML).
>>>>>>>>>> type(MediaType.APPLICATION_XML).
>>>>>>>>>>
>>>>>>>>>> entity(BindingUtility.marshalObject(removeRequest)).
>>>>>>>>>> //marshalls RemoveObjectsRequest object to String
>>>>>>>>>> put(ClientResponse.class);
>>>>>>>>>>
>>>>>>>>>> When my putRequest() resource method is called, I expect the
>>>>>>>>>> req param to be set to an object of type
>>>>>>>>>> RemoveObjectsRequest. Instead it is set to a an object where
>>>>>>>>>> the type is RegistryRequestType and data members of the
>>>>>>>>>> RemoveObjectsRequest are not set.
>>>>>>>>>>
>>>>>>>>>> Is this a issue in jersey (note I am using 1.10) or do I have
>>>>>>>>>> faulty assumption on what to expect?
>>>>>>>>>>
>>>>>>>>>> If the expected behavior is not possible then what is the way
>>>>>>>>>> to get the raw entity from the request within my resource
>>>>>>>>>> method so I can unmarshall it as needed.
>>>>>>>>>>
>>>>>>>>>> Thank you for your help.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I was able to workaround the issue by specifying a String
>>>>>>>>> param in my resource method for receiving the request entity.
>>>>>>>>> I then used my JAXB unmarshaller to unmarshall from a
>>>>>>>>> StringReader created with that String.
>>>>>>>>>
>>>>>>>>> @PUT
>>>>>>>>> @Consumes({"application/xml"})
>>>>>>>>> @Produces({"application/xml"})
>>>>>>>>> @Path("/requests")
>>>>>>>>> public Response putRequest(String entityStr) {
>>>>>>>>> try {
>>>>>>>>> StringReader reader = new StringReader(entityStr);
>>>>>>>>> Unmarshaller u = ...;
>>>>>>>>> RegistryRequestType req = (RegistryRequestType)
>>>>>>>>> u.unmarshal(reader);
>>>>>>>>>
>>>>>>>>> //The req object is now correctly an instance of
>>>>>>>>> RemoveObjectsRequest
>>>>>>>>>
>>>>>>>>> ...
>>>>>>>>> return response;
>>>>>>>>> } catch (JAXBException ex) {
>>>>>>>>> ...
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I am still curious why the behavior I expected is not what
>>>>>>>>> jersey server does.
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
>