agorapulse / grails-facebook-sdk

Facebook SDK Grails Plugin
http://agorapulse.github.com/grails-facebook-sdk/guide
30 stars 13 forks source link

Problem initializing facebookContext at application startup #67

Closed PatrickHuetter closed 10 years ago

PatrickHuetter commented 10 years ago

Using grails 2.3.8 and your plugin in version 0.6.2 i can't start my grails application.

| Error 2014-05-18 20:50:50,946 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: Error creating bean with name 'passBee.UserController': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facebookContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Message: Error creating bean with name 'passBee.UserController': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facebookContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

I'm using facebookContext as described in the documentation in my Grails Controller. At the top of the controller i declared

FacebookContext facebookContext

It's in scope request, so why is there a problem during startup?

benorama commented 10 years ago

Indeed, by default, Grails Controller scope are now Singleton. Check this parameter in your Config.groovy:

// The default scope for controllers. May be prototype, session or singleton.
// If unspecified, controllers are prototype scoped.
grails.controllers.defaultScope = 'singleton'

Since FacebookContext should be instantiated at each request you must use prototype scope.

// The default scope for controllers. May be prototype, session or singleton.
// If unspecified, controllers are prototype scoped.
grails.controllers.defaultScope = 'prototype'

I'm going to add this info in the README file.

PatrickHuetter commented 10 years ago

@benorama Thanks for this information. It works now. Isn't it bad to use prototype as scope? I've seen some comments on stackoverflow.com on that: http://stackoverflow.com/questions/18875181/when-to-decide-to-change-the-scope-of-a-grails-controller

Do you know wich performance impacts the change to prototype has? (some experience?)

benorama commented 10 years ago

Indeed, singleton is "theoretically" better than prototype scope.

I don't have any figures about performance cost of prototype scope, but the cost of recreating a controller instance should be minimal compared to other usual server side performance hogs (external calls such as DB or APIs) or complete client side page load time (several seconds).

We use prototype scope in production and our average server response time in 175ms. I don't think that using singleton scope will improve much things :). For usual web apps, prototype scope should be fine.

eletype commented 9 years ago

Is it possible to use the facebookContext inside of a Quartz job (i.e. outside of a web request)? I have a service that gets facebookContext injected into it. If I access this service from my Quartz job, I get this error. I had to originally set the controller scope to "prototype" to make it work when accessing through a controller, but now I seem to be stuck.

Any thoughts?

benorama commented 9 years ago

Indeed, facebookContext should be injected and used in controllers. You might want to refactor your code to manipulate facebookContext from the controller and pass the required parameters to the service (instead of injecting the facebookContext into the service). What do you need the entire facebookContext inside a service called from a job?

eletype commented 9 years ago

I'm ultimately just trying to instantiate a FacebookGraphClient. Kinda like this:

new FacebookGraphClient(accessToken: facebookContext.app.token)

So I'm ultimately just using it to get the app token. I have the app ID and security in my Config.groovy. I guess I'll just have to create the client manually.

benorama commented 9 years ago

Indeed, that's the way to go.