users@jersey.java.net

[Jersey] Re: Client config (?) or other databinding problems in composition context

From: Michael Iles <michael.iles_at_gmail.com>
Date: Tue, 28 Jan 2014 09:35:16 -0500

You don't need a custom ObjectMapper, you just need to be able to
create the ObjectMapper yourself so that you can then call
`.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)` on it,
as opposed to having the Jersey auto-discovery and the Jackson feature
create it for you.

Also you don't need `JacksonJaxbJsonProvider`: it's just a small
subclass of `JacksonJsonProvider` and if you're not using JAXB (i.e.
you're not using XML) then you should just use `JacksonJsonProvider`.

Again: there isn't any additional code, you don't need to subclass
ObjectMapper or write a new Feature.

In the example I gave I'm registering things directly in the app class
derived from `ResourceConfig` but as Pedro says you can probably also
use a `ContextResolver` to provide the ObjectMapper instance. If you
get that working then please share with the list: I tried and failed
at one point to get a `ContextResolver` working but I didn't pursue
it.

Mike

On 27 January 2014 17:12, Jack Lista <jackalista_at_gmail.com> wrote:
> Hi Mike,
>
> Thanks for the reply, much appreciated. You mean there's no way to
> configure the Jackson code? OMG, that's unreal... we aren't even using a
> custom object mapper, and I would prefer not to use any custom things like
> that unless we have to. So what you're saying is that unless you create a
> custom object mapper, you won't get a chance to get a reference to the
> object mapper used internally and therefore won't get a chance to provide
> any configuration? So, to allow you to configure serialization features,
> you are opening up that jar, removing the META-INF/services and then
> re-jarring it to prevent auto-discovery and then are explicitly registering
> the JAXB provider with your embedded ObjectMapper? Holy crap, this is not
> good news...
>
> Can you share the ObjectMapper code? We are not using a custom object
> mapper, so I'm not sure what that would look like. Also, where did you get
> the JacksonJaxbJsonProvider? We're not using JAXB so would just want to use
> the regular POJO support in Jackson. Can you share that provider code as
> well, by any chance? Also, is there a POJO Jackson provider as well as the
> JAXB one? Where did you learn about this stuff, if you don't mind me
> asking?
>
>
> On Mon, Jan 27, 2014 at 1:48 PM, Michael Iles <michael.iles_at_gmail.com>
> wrote:
>>
>> I don't think it's possible to configure the Jackson feature with the
>> way Jersey 2 is set up right now.
>>
>> If you include the Jackson jar containing the JAX-RS provider
>> (currently jackson-jaxrs-json-provider-2.2.3.jar) then Jersey will
>> auto-discover the Jackson provider and register it, and there's no way
>> for you to configure it.
>>
>> I need to do this as well, and my solution right now is to remove the
>> META-INF/services directory from that Jackson jar.
>>
>> Once you've done that you can then create your own ObjectMapper and
>> register it with Jersey, something like this:
>>
>> public class MyApp extends ResourceConfig {
>> public MyApp() {
>> ObjectMapper om = new ObjectMapper();
>> om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
>> JacksonJaxbJsonProvider provider = new
>> JacksonJaxbJsonProvider();
>> provider.setMapper(om);
>> register(provider);
>> }
>> }
>>
>> Mike.
>>
>> On 27 January 2014 16:30, Jack Lista <jackalista_at_gmail.com> wrote:
>> > Hi Jakub,
>> >
>> > I will try to send you a pared down application so you can see that
>> > behavior. I need to figure out how to set
>> > SerializationFeature.FAIL_ON_EMPTY_BEANS to false, but hopefully once I
>> > get
>> > this stuff working, I can chop the project down to something more
>> > manageable
>> > and send it to you.
>> >
>> > Basically, the @JsonIgnore tags are ignored when I use the
>> > register(JacksonFeature) idiom. Also, if I do the same with Moxy, i.e.
>> > register(MoxyJsonFeature), I get 500 server errors on every request.
>> >
>> > If you can point me toward how to set:
>> >
>> > SerializationFeature.FAIL_ON_EMPTY_BEANS -> False
>> >
>> > I may be able to get to this sooner. Thanks Jakub!
>> >
>> >
>> > On Mon, Jan 27, 2014 at 5:44 AM, Jakub Podlesak
>> > <jakub.podlesak_at_oracle.com>
>> > wrote:
>> >>
>> >> Hi Jack,
>> >>
>> >> It is a good news you found out a working configuration. Thanks for
>> >> sharing the information.
>> >>
>> >> Regarding META-INF/services discovery, there is a serious bug in Jersey
>> >> (JERSEY-2335) that prevents
>> >> Jackson provider to lookup customer supplied object mapper. More
>> >> details
>> >> including a workaround could be found
>> >> in another thread here:
>> >> https://java.net/projects/jersey/lists/users/archive/2014-01/message/91
>> >>
>> >> On the Jackson provider does not honour the @JsonIgnore annotation:
>> >> could
>> >> you please share
>> >> a simple reproducible test case, that i can debug locally? I have no
>> >> idea
>> >> on what could be causing
>> >> this odd behaviour, other then a non-Jackson provider has been
>> >> involved.
>> >>
>> >> Please feel free to file a new bug report for that.
>> >>
>> >> Thanks,
>> >>
>> >> ~Jakub
>> >>
>> >>
>> >>
>> >> On 18 Jan 2014, at 01:37, Jack Lista <jackalista_at_gmail.com> wrote:
>> >>
>> >> I see... that's frustrating. It seems odd that you can't do that
>> >> considering how much effort has been put into configuration facilities.
>> >> So
>> >> it is the META-INF/services autodiscovery that is how Jackson is
>> >> getting
>> >> registered? I have been wondering about that, it sounds like you think
>> >> that's what's happening in my case. I'm curious about your opinion
>> >> because
>> >> I am honestly clueless, when it comes right down to it, but the moxy
>> >> jars
>> >> aren't in my war so it couldn't be moxy. It's touchy,
>> >> configuration-wise,
>> >> it seems but we've found a configuration that handles our domain model
>> >> and
>> >> various uses of generics and whatnot, but damn, we spent a *long* time
>> >> getting there.
>> >>
>> >> If the META-INF/services thing goes away I may have to revisit this,
>> >> but
>> >> for now, we seem to be good. I wish I could get it to work by
>> >> registering
>> >> the JacksonFeature but it completely ignores all the @JsonIgnore tags
>> >> in our
>> >> domain model, and I haven't figured out how to change that so I guess
>> >> letting it auto-register itself is going to have to suffice. Any idea
>> >> why
>> >> Jackson would ignore the @JsonIgnore tags when registered via the
>> >> JacksonFeature and would honor them when auto-registered? I would love
>> >> to
>> >> know that as well...
>> >>
>> >> In other news, I just tried using Links embedded in Responses and
>> >> that's
>> >> really easy to use and works nicely from what I've seen so far, and
>> >> that's
>> >> pretty cool, but I am still a bit in the dark WRT Jackson registration.
>> >> Thanks for your response...
>> >>
>> >> --j
>> >>
>> >>
>> >> On Tue, Jan 14, 2014 at 7:38 PM, Michael Iles <michael.iles_at_gmail.com>
>> >> wrote:
>> >>>
>> >>> FWIW I'm fine with the META-INF/services auto discovery... my problem
>> >>> is that Jersey doesn't give me a way to access the Jackson provider
>> >>> that it auto-discovers so that I can configure it. If Jersey allowed
>> >>> me to get a handle to the provider that it discovered then I could
>> >>> call `setMapper(...)` on the provider and I wouldn't have to munge the
>> >>> Jackson provider jar.
>> >>>
>> >>> Mike.
>> >>>
>> >>> On 14 January 2014 18:46, Jack Lista <jackalista_at_gmail.com> wrote:
>> >>> > OK, I *think* I sorted this out, since there seems to be much
>> >>> > confusion
>> >>> > about configuration, I'll post what I found and hopefully this will
>> >>> > clarify
>> >>> > things for the next poor sap who comes along.
>> >>> >
>> >>> > I tried various mvn dependencies (see my first email on this subject
>> >>> > for the
>> >>> > initial 2 jackson dep's, for data-bind and annotations) and found
>> >>> > that
>> >>> > if I
>> >>> > just use the provider dep from the jackson github site I have *only*
>> >>> > jackson
>> >>> > json jars (6 of them), and all from the right version (2.3.0 in my
>> >>> > case). I
>> >>> > have another dep for moxy, and if I add that, then I see moxy jars
>> >>> > in
>> >>> > WEB-IN/lib, but as long as I use only the dep listed here, I get
>> >>> > only
>> >>> > jackson 2.3.0.
>> >>> >
>> >>> > From here:
>> >>> >
>> >>> > https://github.com/FasterXML/jackson-jaxrs-providers
>> >>> >
>> >>> > <dependency>
>> >>> > <groupId>com.fasterxml.jackson.jaxrs</groupId>
>> >>> > <artifactId>jackson-jaxrs-json-provider</artifactId>
>> >>> >
>> >>> > <version>${jackson.version}</version>
>> >>> > </dependency>
>> >>> >
>> >>> > I have been concerned about the fact that I was not using any
>> >>> > "Features"
>> >>> > related to JSON (but it was working anyway...), and also because
>> >>> > moxy
>> >>> > is the
>> >>> > default I was a bit worried that we might be using moxy if not
>> >>> > providing any
>> >>> > configuration at all, which I wasn't. However, I found a notice on
>> >>> > the
>> >>> > Jackson github site above that says that the Jackson (2.2 onward)
>> >>> > provider
>> >>> > performs (some sort of) auto-registration.
>> >>> >
>> >>> > The 6 jars produced by the above dependency are these:
>> >>> >
>> >>> > jackson-annotations-2.3.0.jar
>> >>> > jackson-core-2.3.0.jar
>> >>> > jackson-databind-2.3.0.jar
>> >>> > jackson-jaxrs-base-2.3.0.jar
>> >>> > jackson-jaxrs-json-provider-2.3.0.jar
>> >>> > jackson-module-jaxb-annotations-2.3.0.jar
>> >>> >
>> >>> > It seems I'm using Jackson 2.3.0, no? With only that above json
>> >>> > dep
>> >>> > in my
>> >>> > pom.xml none of the moxy jars appear to be present so I think I am
>> >>> > safely
>> >>> > using jackson. Please correct me if I'm wrong, you don't need to
>> >>> > be
>> >>> > polite! ;)
>> >>> >
>> >>> > I was wondering if the reason that Jackson auto-registers itself is
>> >>> > related
>> >>> > to the current discussion about META-INF services. Does anyone know
>> >>> > if
>> >>> > these two things are related? I've seen comments about how this
>> >>> > META-INF
>> >>> > stuff is breaking some integrations, but I'm not clear on the
>> >>> > details.
>> >>> > The
>> >>> > gist of those conversations seems to be that the META-INF stuff
>> >>> > should
>> >>> > be
>> >>> > removed, and that Tatu (Jackson author) will do this at some point.
>> >>> > Should
>> >>> > I then expect the auto registration I'm currently enjoying to stop
>> >>> > working
>> >>> > or are these two things not related? If anyone is clear about this
>> >>> > stuff
>> >>> > (I'm obviously far from clear) I'd love to hear from you...
>> >>> >
>> >>> > --j
>> >>> >
>> >>> >
>> >>> > On Mon, Jan 13, 2014 at 5:06 PM, Jack Lista <jackalista_at_gmail.com>
>> >>> > wrote:
>> >>> >>
>> >>> >> I got server side log file tracing turned on, it turns out that in
>> >>> >> addition to the properties you need to set that I mentioned in my
>> >>> >> previous
>> >>> >> post, you also have to register the LoggingFilter. I added this to
>> >>> >> my
>> >>> >> application sublass and I now get *minor* amounts of trace info
>> >>> >> showing up:
>> >>> >>
>> >>> >> import import org.glassfish.jersey.filter.LoggingFilter;
>> >>> >> ...
>> >>> >> register(LoggingFilter.class);
>> >>> >>
>> >>> >>
>> >>> >> I also tried regsitering like this:
>> >>> >>
>> >>> >> import import org.glassfish.jersey.filter.LoggingFilter;
>> >>> >> import javax.ws.rs.container.ContainerRequestFilter;
>> >>> >> import javax.ws.rs.container.ContainerResponseFilter;
>> >>> >> ...
>> >>> >> register(LoggingFilter.class, ContainerRequestFilter.class).
>> >>> >> register(LoggingFilter.class, ContainerResponseFilter.class);
>> >>> >>
>> >>> >> The effect appears the same with both means of registering the
>> >>> >> logging
>> >>> >> filter. Unfortunately, none of the tracing, even at the VERBOSE
>> >>> >> level
>> >>> >> of
>> >>> >> detail, is telling me what JSON marshalling / unmarshalling is
>> >>> >> being
>> >>> >> used.
>> >>> >> I have it set to verbose, but that's not very verbose in my view,
>> >>> >> it's
>> >>> >> just
>> >>> >> giving me a little bit about the HTTP request/response. In fact,
>> >>> >> the
>> >>> >> runtime is barely even mentioning JSON beyond what's in accept
>> >>> >> headers
>> >>> >> (request) and content type (response). On the response side, this
>> >>> >> is
>> >>> >> all I
>> >>> >> see:
>> >>> >>
>> >>> >> Jan 13, 2014 4:11:09 PM org.glassfish.jersey.filter.LoggingFilter
>> >>> >> log
>> >>> >> INFO: 3 * Server responded with a response on thread
>> >>> >> http-bio-8080-exec-6
>> >>> >> 3 < 201
>> >>> >> 3 < Content-Type: application/json
>> >>> >> 3 < Location: http://blahblahblah...
>> >>> >>
>> >>> >> There's also mention of the accept header in the request tracing:
>> >>> >>
>> >>> >> 4 > accept: application/json
>> >>> >>
>> >>> >> That's it, no other mention of JSON in any form. How do I get the
>> >>> >> runtime
>> >>> >> to tell me what JSON infrastructure I'm using?? Is there a
>> >>> >> different
>> >>> >> means
>> >>> >> of registering the LoggingFilter that will make it spit out more
>> >>> >> info?
>> >>> >>
>> >>> >> I am getting bi-directional databinding, I can serialize my POJOs
>> >>> >> to
>> >>> >> JSON
>> >>> >> and can deserialize them back into java objects, but I want to see
>> >>> >> what JSON
>> >>> >> processing I'm using, as I haven't registered any JSON provider or
>> >>> >> feature,
>> >>> >> all I did was put the 2.3.1 Jackson dependencies in my pom.xml. I
>> >>> >> want to
>> >>> >> do a sanity check on what I'm doing and make sure I'm not using a
>> >>> >> horked
>> >>> >> configuration. How do I get more info on my JSON configuration?
>> >>> >>
>> >>> >> I tried registering the following in my App (ResourceConfig)
>> >>> >> subclass,
>> >>> >> but
>> >>> >> I'm explicitly *not* using either of these, as they both threw
>> >>> >> exceptions
>> >>> >> when I registered them (individually, I didn't register them both
>> >>> >> at
>> >>> >> once):
>> >>> >>
>> >>> >> ...
>> >>> >> register(JacksonFeature.class);
>> >>> >> register(MoxyJsonFeature.class);
>> >>> >>
>> >>> >> I'd like to figure out how I can validate that my JSON processing
>> >>> >> stuff is
>> >>> >> properly configured, but so far I can't seem to get any visibility
>> >>> >> into it.
>> >>> >> How do you get more info on this? Is there deeper tracing? Is
>> >>> >> there
>> >>> >> some
>> >>> >> other means?
>> >>> >>
>> >>> >> You know how you can set a flag in hibernate and you get more gory
>> >>> >> detail
>> >>> >> on the SQL it's using than you could ever want? *That's* what I
>> >>> >> want
>> >>> >> here,
>> >>> >> some module is marshaling this stuff and unmarshaling it and I want
>> >>> >> to
>> >>> >> turn
>> >>> >> on logging in that module so I can see what module it is and what's
>> >>> >> going
>> >>> >> on... How do you do that?
>> >>> >>
>> >>> >> Thanks...
>> >>> >>
>> >>> >>
>> >>> >> On Mon, Jan 13, 2014 at 3:24 PM, Jack Lista <jackalista_at_gmail.com>
>> >>> >> wrote:
>> >>> >>>
>> >>> >>> Hi Jakub, Jersey folks,
>> >>> >>>
>> >>> >>> I'm trying to turn on server side log file tracing to see what
>> >>> >>> JSON
>> >>> >>> databinding I'm using and am having trouble finding out how to
>> >>> >>> successfully
>> >>> >>> get actual logs to show up in a log file.
>> >>> >>>
>> >>> >>> I set these properties in my Application class:
>> >>> >>>
>> >>> >>> property("jersey.config.server.tracing", "ALL").
>> >>> >>> property("jersey.config.server.tracing.threshold", "TRACE");
>> >>> >>>
>> >>> >>> Next I got an error related to headers buffer space, so I added
>> >>> >>> the
>> >>> >>> following to my tomcat's server.xml:
>> >>> >>>
>> >>> >>> <Connector port="8080" protocol="HTTP/1.1"
>> >>> >>> connectionTimeout="20000"
>> >>> >>> maxHttpHeaderSize="16384" <------------I
>> >>> >>> added
>> >>> >>> this, and the error stopped
>> >>> >>> redirectPort="8443" />
>> >>> >>>
>> >>> >>> I'm pretty sure now that logging/tracing is now turned on, but I
>> >>> >>> still
>> >>> >>> don't see anything. Where is this logging supposed to show up?
>> >>> >>> I'm
>> >>> >>> not
>> >>> >>> seeing it in catalina.out, is this stuff directed to a different
>> >>> >>> log
>> >>> >>> file?
>> >>> >>>
>> >>> >>> I've seen chapter 19 (Tracing and Monitoring) here:
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>>
>> >>> >>> https://jersey.java.net/documentation/latest/monitoring_tracing.html#tracing
>> >>> >>>
>> >>> >>> It says that that there's a "dedicated logger" for java for server
>> >>> >>> side
>> >>> >>> log file tracing, but what do you actually have to do to make it
>> >>> >>> log
>> >>> >>> things?
>> >>> >>> I have been scouring the web for details and there are a few pages
>> >>> >>> but they
>> >>> >>> all seem to be relevant to Jersey 1.x and don't seem applicable.
>> >>> >>> What do
>> >>> >>> you have to do to get the trace info to show up in a server side
>> >>> >>> log
>> >>> >>> file?
>> >>> >>>
>> >>> >>>
>> >>> >>> On Thu, Jan 9, 2014 at 8:53 AM, Jakub Podlesak
>> >>> >>> <jakub.podlesak_at_oracle.com> wrote:
>> >>> >>>>
>> >>> >>>> Hi Jack,
>> >>> >>>>
>> >>> >>>> ad 1) it is hard to tell from the information you provided.
>> >>> >>>> Anyway, you should be able to determine the effective
>> >>> >>>> worker
>> >>> >>>> used
>> >>> >>>> if you set Jersey's server side config property,
>> >>> >>>> jersey.config.server.tracing,
>> >>> >>>> to "ALL". Then the actual worker used at runtime should
>> >>> >>>> get
>> >>> >>>> logged.
>> >>> >>>>
>> >>> >>>> ad 2) i guess this is rather a question for Jackson mailing list,
>> >>> >>>> if
>> >>> >>>> it
>> >>> >>>> turns out one of the Jackson
>> >>> >>>> providers is used and the annotation is not mandated. Let's
>> >>> >>>> clarify the first thing first.
>> >>> >>>>
>> >>> >>>> Cheers,
>> >>> >>>>
>> >>> >>>> ~Jakub
>> >>> >>>>
>> >>> >>>>
>> >>> >>>> On 08 Jan 2014, at 17:53, Jack Lista <jackalista_at_gmail.com>
>> >>> >>>> wrote:
>> >>> >>>>
>> >>> >>>> And yes, your more compact syntax works nicely, thank you very
>> >>> >>>> much!
>> >>> >>>> If
>> >>> >>>> you wouldn't mind, would you please answer those two dumb
>> >>> >>>> questions
>> >>> >>>> about
>> >>> >>>> 1.) which databinding I'm actually using and 2.) the question
>> >>> >>>> about
>> >>> >>>> @JsonIgnore?
>> >>> >>>>
>> >>> >>>> Much thanks sir...
>> >>> >>>>
>> >>> >>>> -=j=-
>> >>> >>>>
>> >>> >>>>
>> >>> >>>> On Wed, Jan 8, 2014 at 8:20 AM, Jack Lista <jackalista_at_gmail.com>
>> >>> >>>> wrote:
>> >>> >>>>>
>> >>> >>>>> Ah, yes! Sweet! So *that's* how you submit a generic type to
>> >>> >>>>> this
>> >>> >>>>> infrastructure!! I had stumbled across something very similar,
>> >>> >>>>> although a
>> >>> >>>>> bit more long winded, as the last thing I tried last night, but
>> >>> >>>>> I
>> >>> >>>>> just
>> >>> >>>>> happened across it based on a comment of the guy I'm working
>> >>> >>>>> with
>> >>> >>>>> on this
>> >>> >>>>> and I tried it and it actually then gave me my wrapper envelope
>> >>> >>>>> back with my
>> >>> >>>>> domain class(es) inside it. Here's the syntax I tried last
>> >>> >>>>> night
>> >>> >>>>> which
>> >>> >>>>> worked (& I'm going to try your more compact form immediately):
>> >>> >>>>>
>> >>> >>>>> GenericType<ResponseEnvelope<FooBar>> fooResponseEnvType = new
>> >>> >>>>> GenericType<ResponseEnvelope<FooBar>>() {};
>> >>> >>>>>
>> >>> >>>>> // then pass fooResponseEnvType to the get(...) method like so:
>> >>> >>>>>
>> >>> >>>>> ResponseEnvelope<FooBar> envelope4ReuseMkt =
>> >>> >>>>> client.target("http://localhost:8080/v1.1/rs")
>> >>> >>>>> .path("foobar")
>> >>> >>>>>
>> >>> >>>>> .path(fooBarId.toString())
>> >>> >>>>>
>> >>> >>>>> .request(MediaType.APPLICATION_JSON_TYPE)
>> >>> >>>>>
>> >>> >>>>> .get(fooResponseEnvType);
>> >>> >>>>>
>> >>> >>>>> Thanks so much for your comment, however, as your code is much
>> >>> >>>>> more
>> >>> >>>>> compact which I like. Where, pray tell, is this stuff
>> >>> >>>>> documented?
>> >>> >>>>> Almost
>> >>> >>>>> *everyone* is using domain objects (or DTOs, etc.) with these
>> >>> >>>>> services, so
>> >>> >>>>> the examples with simple String data types aren't representative
>> >>> >>>>> of
>> >>> >>>>> the
>> >>> >>>>> techniques needed to work with domain objects, generic types and
>> >>> >>>>> other
>> >>> >>>>> things commonly found in enterprise environments (like the
>> >>> >>>>> GenericType
>> >>> >>>>> utility class you pointed out). We have a pretty crazy domain
>> >>> >>>>> model, so I
>> >>> >>>>> am going to need to get much more deeply into things like this,
>> >>> >>>>> where is
>> >>> >>>>> this GenericType utility discussed, beyond a javadoc?
>> >>> >>>>>
>> >>> >>>>> I would also *really* love to understand what such facilities
>> >>> >>>>> exist,
>> >>> >>>>> how they're intended to be used, what kids of functionality is
>> >>> >>>>> currently
>> >>> >>>>> support and even, if you guys know, what direction things are
>> >>> >>>>> headed in.
>> >>> >>>>> I've been over (I think) most of the
>> >>> >>>>> https://jersey.java.net/documentation/latest... site but I
>> >>> >>>>> haven't
>> >>> >>>>> found
>> >>> >>>>> discussion of things like GenericType, sorry if I'm being dense
>> >>> >>>>> but
>> >>> >>>>> can you
>> >>> >>>>> point that out? (Thanks again.)
>> >>> >>>>>
>> >>> >>>>> While I have your ear, can you answer two relatively simple
>> >>> >>>>> questions?
>> >>> >>>>> My services are working when I don't explicitly register any
>> >>> >>>>> JSON
>> >>> >>>>> Features
>> >>> >>>>> at all, but I do have these mvn dependencies in my pom.xml:
>> >>> >>>>>
>> >>> >>>>>
>> >>> >>>>> <dependency>
>> >>> >>>>> <groupId>com.fasterxml.jackson.core</groupId>
>> >>> >>>>> <artifactId>jackson-databind</artifactId>
>> >>> >>>>> <version>${jackson.version}</version>
>> >>> >>>>> </dependency>
>> >>> >>>>>
>> >>> >>>>> <dependency>
>> >>> >>>>> <groupId>com.fasterxml.jackson.core</groupId>
>> >>> >>>>> <artifactId>jackson-annotations</artifactId>
>> >>> >>>>> <version>${jackson.version}</version>
>> >>> >>>>> </dependency>
>> >>> >>>>>
>> >>> >>>>> What JSON databinding am I using? If I explicitly enable the
>> >>> >>>>> JacsonFeature, I get very different behavior (stackoverflow
>> >>> >>>>> errors).
>> >>> >>>>>
>> >>> >>>>> The second dumb question is, is the @JsonIgnore annotation in
>> >>> >>>>> domain
>> >>> >>>>> classes still how you are supposed to prevent recursive
>> >>> >>>>> stackoverflow JSON
>> >>> >>>>> serialization errors? I ask because if I explicitly enable the
>> >>> >>>>> JacksonFeature as I described in my post, I would assume that I
>> >>> >>>>> am
>> >>> >>>>> definitely using Jackson but the @JsonIgnore annotations within
>> >>> >>>>> my
>> >>> >>>>> domain
>> >>> >>>>> classes appear to be ignored themselves and I suffer
>> >>> >>>>> stackoverflow
>> >>> >>>>> errors.
>> >>> >>>>> We have a very complex domain model so I want to stay on top of
>> >>> >>>>> the
>> >>> >>>>> best
>> >>> >>>>> techniques for managing domain classes that have a lot of
>> >>> >>>>> relationships
>> >>> >>>>> among them.
>> >>> >>>>>
>> >>> >>>>> Thanks Jakub, appreciate your help *immensely*!
>> >>> >>>>>
>> >>> >>>>> -=j=-
>> >>> >>>>>
>> >>> >>>>>
>> >>> >>>>>
>> >>> >>>>> On Wed, Jan 8, 2014 at 5:30 AM, Jakub Podlesak
>> >>> >>>>> <jakub.podlesak_at_oracle.com> wrote:
>> >>> >>>>>>
>> >>> >>>>>> Hi Jack,
>> >>> >>>>>>
>> >>> >>>>>> Please try to use the following type when reading the entity:
>> >>> >>>>>>
>> >>> >>>>>> ResponseEnvelope<FooBar> envelope = svcResponse.readEntity(new
>> >>> >>>>>> javax.ws.rs.core.GenericType<ResponseEnvelope<FooBar>>(){});
>> >>> >>>>>>
>> >>> >>>>>> Does it help?
>> >>> >>>>>>
>> >>> >>>>>> ~Jakub
>> >>> >>>>>>
>> >>> >>>>>>
>> >>> >>>>>> On 07 Jan 2014, at 22:05, Jack Lista <jackalista_at_gmail.com>
>> >>> >>>>>> wrote:
>> >>> >>>>>>
>> >>> >>>>>> Hi,
>> >>> >>>>>>
>> >>> >>>>>> I'm trying to get a composition working in which I'm having
>> >>> >>>>>> trouble
>> >>> >>>>>> getting my entity back from the Response even though the actual
>> >>> >>>>>> service
>> >>> >>>>>> request seems to have succeeded. I'm using Jersey 2.5.1 and am
>> >>> >>>>>> using the
>> >>> >>>>>> client API to have one service call another 2 services and then
>> >>> >>>>>> do
>> >>> >>>>>> some
>> >>> >>>>>> processing based on the results of the 2 composed services.
>> >>> >>>>>>
>> >>> >>>>>> I'm having no trouble getting the two services being composed
>> >>> >>>>>> to
>> >>> >>>>>> work,
>> >>> >>>>>> marshaling the POJO service payload as JSON. If I call either
>> >>> >>>>>> service in a
>> >>> >>>>>> browser they both work and spit out the appropriate JSON
>> >>> >>>>>> content.
>> >>> >>>>>> Additionally, when I call them from within the composing
>> >>> >>>>>> service,
>> >>> >>>>>> it appears
>> >>> >>>>>> that the calls have succeeded. Printing the Response via a
>> >>> >>>>>> logger
>> >>> >>>>>> shows the
>> >>> >>>>>> following:
>> >>> >>>>>>
>> >>> >>>>>> svcResponse: InboundJaxrsResponse{ClientResponse{method=GET,
>> >>> >>>>>> uri=http://localhost:8080/v1.1/rs/foobar/1, status=200,
>> >>> >>>>>> reason=OK}}
>> >>> >>>>>>
>> >>> >>>>>> Additionally, if I call (Response) svcResponse.hasEntity() I
>> >>> >>>>>> get a
>> >>> >>>>>> result of true.
>> >>> >>>>>>
>> >>> >>>>>> However, when I try to call readEntity(), I get a class cast
>> >>> >>>>>> exception:
>> >>> >>>>>>
>> >>> >>>>>> java.lang.ClassCastException: java.util.LinkedHashMap cannot be
>> >>> >>>>>> cast
>> >>> >>>>>> to com.baz.domain.FooBar
>> >>> >>>>>>
>> >>> >>>>>>
>> >>> >>>>>> A few details of my implementation that may be relevant are
>> >>> >>>>>> that
>> >>> >>>>>> we
>> >>> >>>>>> are using an application class that subclasses ResourceConfig
>> >>> >>>>>> (without a
>> >>> >>>>>> web.xml). This app class also uses the following package
>> >>> >>>>>> scanning
>> >>> >>>>>> call to
>> >>> >>>>>> find our annotated classes:
>> >>> >>>>>>
>> >>> >>>>>> packages("com.baz.rest");
>> >>> >>>>>>
>> >>> >>>>>> The POJO domain model classes being returned are not in that
>> >>> >>>>>> package,
>> >>> >>>>>> as the above snippet of stacktrace shows, but they are being
>> >>> >>>>>> marshaled to
>> >>> >>>>>> JSON without issue, so I suspect that's not a problem.
>> >>> >>>>>>
>> >>> >>>>>> I'm not registering any JSON provider, but have the following
>> >>> >>>>>> in
>> >>> >>>>>> my
>> >>> >>>>>> pom.xml which seems to have enabled Jackson:
>> >>> >>>>>>
>> >>> >>>>>> <dependency>
>> >>> >>>>>> <groupId>com.fasterxml.jackson.core</groupId>
>> >>> >>>>>> <artifactId>jackson-databind</artifactId>
>> >>> >>>>>> <version>${jackson.version}</version>
>> >>> >>>>>> </dependency>
>> >>> >>>>>>
>> >>> >>>>>> <dependency>
>> >>> >>>>>> <groupId>com.fasterxml.jackson.core</groupId>
>> >>> >>>>>> <artifactId>jackson-annotations</artifactId>
>> >>> >>>>>> <version>${jackson.version}</version>
>> >>> >>>>>> </dependency>
>> >>> >>>>>>
>> >>> >>>>>> I have also tried using the following in my pom.xml but it
>> >>> >>>>>> seems
>> >>> >>>>>> to
>> >>> >>>>>> make no difference whether it's present or not:
>> >>> >>>>>>
>> >>> >>>>>> <dependency>
>> >>> >>>>>> <groupId>org.glassfish.jersey.media</groupId>
>> >>> >>>>>> <artifactId>jersey-media-json-jackson</artifactId>
>> >>> >>>>>> </dependency>
>> >>> >>>>>>
>> >>> >>>>>> It is necessary for compilation if I explicitly register the
>> >>> >>>>>> JacksonFeature, but seems to have no effect otherwise.
>> >>> >>>>>>
>> >>> >>>>>> I'm using a simple unadorned client created in the composing
>> >>> >>>>>> service
>> >>> >>>>>> (the one that is calling the other two services):
>> >>> >>>>>>
>> >>> >>>>>> Client client = ClientBuilder.newClient();
>> >>> >>>>>>
>> >>> >>>>>> I'm also creating a webTarget and an invocation in the
>> >>> >>>>>> following
>> >>> >>>>>> manner:
>> >>> >>>>>>
>> >>> >>>>>> WebTarget webTarget =
>> >>> >>>>>> client.target("http://localhost:8080/v1.1/rs");
>> >>> >>>>>> Invocation.Builder invocationBuilder = webTarget
>> >>> >>>>>> .path("foobar")
>> >>> >>>>>> .path(foobarId.toString())
>> >>> >>>>>> .request(MediaType.APPLICATION_JSON_TYPE);
>> >>> >>>>>> Response svcResponse = invocationBuilder.get(Response.class);
>> >>> >>>>>>
>> >>> >>>>>>
>> >>> >>>>>> I've tried explicitly enabling Jackson by adding the following
>> >>> >>>>>> call in
>> >>> >>>>>> my application subclass:
>> >>> >>>>>>
>> >>> >>>>>> register(JacksonFeature.class);
>> >>> >>>>>>
>> >>> >>>>>> and adding a similar call in the client code like this:
>> >>> >>>>>>
>> >>> >>>>>> Client client =
>> >>> >>>>>> ClientBuilder.newClient().register(JacksonFeature.class);
>> >>> >>>>>>
>> >>> >>>>>> However, when I configure the server and client that way, the
>> >>> >>>>>> Jackson
>> >>> >>>>>> databinding doesn't respect the @JsonIgnore annotations in our
>> >>> >>>>>> domain model
>> >>> >>>>>> and suffers a stackoverflow error. Without that explicit
>> >>> >>>>>> configuration, I
>> >>> >>>>>> get nice decent sized chunks of JSON which do respect the
>> >>> >>>>>> @JsonIgnore
>> >>> >>>>>> annotations in our domain model. I've also tried to switch to
>> >>> >>>>>> the
>> >>> >>>>>> Moxy JSON
>> >>> >>>>>> code by adding "register(MoxyJsonFeature.class);" to the
>> >>> >>>>>> application class
>> >>> >>>>>> and calling "Client client =
>> >>> >>>>>> ClientBuilder.newClient().register(MoxyJsonFeature.class);" in
>> >>> >>>>>> the
>> >>> >>>>>> client
>> >>> >>>>>> code but this simply results in 500 errors even when calling
>> >>> >>>>>> the 2
>> >>> >>>>>> composed
>> >>> >>>>>> services in a browser. When I do no configuration in either
>> >>> >>>>>> the
>> >>> >>>>>> application
>> >>> >>>>>> subclass or in the client code in the calling service as
>> >>> >>>>>> originally shown
>> >>> >>>>>> above, I get the proper JSON representation in a browser from
>> >>> >>>>>> each
>> >>> >>>>>> of the
>> >>> >>>>>> two composed services.
>> >>> >>>>>>
>> >>> >>>>>> The problem occurs when I try to access the entity from the
>> >>> >>>>>> response.
>> >>> >>>>>> This first call succeeds:
>> >>> >>>>>>
>> >>> >>>>>> ResponseEnvelope<FooBar> envelope =
>> >>> >>>>>> svcResponse.readEntity(ResponseEnvelope.class);
>> >>> >>>>>>
>> >>> >>>>>> However, I get the class cast exception referencing a
>> >>> >>>>>> LinkedHashMap
>> >>> >>>>>> (?!?) when I try the following call:
>> >>> >>>>>>
>> >>> >>>>>> FooBar fooBar = envelope.getPayload();
>> >>> >>>>>>
>> >>> >>>>>> Perhaps the problem is related to our envelope class that has a
>> >>> >>>>>> generic domain class embedded in it? However, Jackson has no
>> >>> >>>>>> trouble
>> >>> >>>>>> marshaling the ResponseEnvelope to JSON, so why would it fail
>> >>> >>>>>> in
>> >>> >>>>>> the
>> >>> >>>>>> opposite direction?
>> >>> >>>>>>
>> >>> >>>>>> I'm utterly confused (obvious? lol), any help would be
>> >>> >>>>>> *greatly*
>> >>> >>>>>> appreciated!
>> >>> >>>>>>
>> >>> >>>>>> --j
>> >>> >>>>>>
>> >>> >>>>>>
>> >>> >>>>>
>> >>> >>>>
>> >>> >>>>
>> >>> >>>
>> >>> >>
>> >>> >
>> >>
>> >>
>> >>
>> >
>
>