grails-gson icon indicating copy to clipboard operation
grails-gson copied to clipboard

GSON problem: custom adapters not used

Open sergiomichels opened this issue 11 years ago • 12 comments

For some reason GSON is failing in get the GsonBuilder from the applicationContext, this causes the class to return a new GsonBuilder() without my custom Adapters. For example:

@Lazy
private GsonBuilder gsonBuilder = {
  GsonBuilder gsonBuilder = applicationContext?.getBean('gsonBuilder', GsonBuilder)
  if(gsonBuilder) {
    println "**** Using applicationContext GsonBuilder"
  } else {
    println "**** Not found bean gsonBuilder"
    gsonBuilder = new GsonBuilder()
  }
  return gsonBuilder
}()

In my case it prints "Not found bean gsonBuilder" and by consequence using render model as GSON fails to use my adapters.

The problem goes away if I explicity declare gsonBuilder in my controller and use render contentType: 'application/json', text: gson.toJson(model)

Maybe it's a problem with ApplicationContextAware? I can also see that applicationContext is null in GSON.

sergiomichels avatar Jun 05 '13 17:06 sergiomichels

I'm experiencing the same problems.

uris77 avatar Jun 06 '13 23:06 uris77

What's the diff between ApplicationContextAware and setting applicationContext in the bean definition? Maybe the issue is with ApplicationContextAware?

sergiomichels avatar Aug 28 '13 03:08 sergiomichels

I believe when going through the GroovyDefaultMethods asType calls, it just constructs the GSON object. Since it never passes through Spring and applicationContext is never set. Without access to the applicationContext, there's no hope that the gsonBuilder can get set.

I think the orignal idea was that since the ArtefactEnhancer is adding the render method and since it has a proper gson object, this could work. But the variable is defined both at the class level and as the argument the closure. Since the argument to the closure is bullocks, we should be using it, but it's scoped as the variable to use. I think the fix is remove the arg from the closure in enhanceControllers(). I'll try locally and see what happens.

quidryan avatar Sep 10 '13 04:09 quidryan

ConvertersDomainTransformer seems responsible for properly creating the GSON converter, but only for Domain objects, not on Controllers.

quidryan avatar Sep 10 '13 07:09 quidryan

Is this a problem with accessing the spring context from a static context when using as GSON? I think the reason it's going down that path is that applicationContext is null – note the ?. operator.

robfletcher avatar Sep 10 '13 09:09 robfletcher

@robfletcher It's just a controller action, not a static method.

sergiomichels avatar Sep 10 '13 11:09 sergiomichels

@sergiomichels yeah, the static-ness is in the gson plugin

robfletcher avatar Sep 10 '13 11:09 robfletcher

@robfletcher I think that using Holders.grailsApplication.mainContext will solve the issue. I will do some tests.

sergiomichels avatar Oct 18 '13 20:10 sergiomichels

hmmm I'm getting a hard time trying to reproduce this again.

sergiomichels avatar Nov 25 '13 23:11 sergiomichels

This is still an issue, I have the same problem: applicationContext is null in GSON when using

render ([date: new Date()] as GSON

My custom DateAdapter is not used in this case.

angelo-v avatar Jan 30 '14 08:01 angelo-v

I made a suggestion in #35.

sergiomichels avatar Jan 30 '14 10:01 sergiomichels

This is potentially solve alb using grails.util.Holders

robfletcher avatar Jan 30 '14 10:01 robfletcher