2017-09-08 2 views
2

J'ai créé une application de test de base sur Grails 3.1.16 qui a deux services, une première et async prévu un service (ex FirstService.) Appelant une deuxième session de scope un service (ex SessionScopeService.), comme ci-dessous:Grails 3.1.16 - Méthode d'appel du service de portée de session du service régulier

"FirstService.groovy ":

import org.springframework.scheduling.annotation.Async 
import org.springframework.scheduling.annotation.Scheduled 

class FirstService { 

    def sessionScopeService 
    boolean lazyInit = false 

    @Async 
    @Scheduled(cron="*/10 * * * * MON-FRI") 
    void firstServiceMethod() { 
     sessionScopeService.serviceMethod() 
    } 
} 

" Ses sionScopeService.groovy « :

class SessionScopeService { 

    static scope = "session" 
    static proxy = "true" 

    def serviceMethod() { 
     log.info("test OK") 
    } 
} 

L'application ne démarre pas, le rapport d'erreurs de la session de portée:

ERROR org.springframework.boot.SpringApplication - Application startup 
failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean 

with name 'firstService': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionScopeService ': Scope 'session' 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. 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:778) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) 
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) 
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) 
at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:55) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:375) 
at grails.boot.GrailsApp.run(GrailsApp.groovy:364) 
at grails.boot.GrailsApp$run.call(Unknown Source) 
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) 
at testservice.Application.main(Application.groovy:8) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionScopeService': Scope 'session' 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. 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:1248) 
at org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory.autowireByName(OptimizedAutowireCapableBeanFactory.java:160) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1198) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) 
... 20 common frames omitted 
Caused by: 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. 
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) 
at org.springframework.web.context.request.SessionScope.get(SessionScope.java:91) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) 
... 25 common frames omitted 

J'ai essayé aussi de créer proxy scope manuellement sur 'resources.groovy':

beans = { 

    sessionScopeServiceProxy(ScopedProxyFactoryBean) { 
     targetBeanName = 'sessionScopeService' 
     proxyTargetClass = true 
    } 
    } 

puis dans FirstService a injecté ce proxy:

def sessionScopeServiceProxy 

mais sans succès (la méthode de "sessionScopeServiceProxy" n'est même pas reconnue par le "FirstService").

Comment puis-je résoudre ce problème? Merci pour votre temps

Répondre

0

Je suppose que vous voulez utiliser une nouvelle instance SessionScopeService chaque fois que votre « travail » fonctionne, alors vous devriez utiliser « prototype » que la portée et obtenir manuellement le grain dans l'exécution firstServiceMethod: grailsApplication.mainContext.getBean(SessionScopeService). De cette façon, chaque fois que votre 'job' sera lancé, un nouveau 'SessionScopeService' sera créé pour cette exécution.

+0

Je vous remercie pour la réponse. Malheureusement je ne peux pas utiliser une session "prototype" dans "SessionScopeService": le code est un exemple simple de projet plus complexe, dans lequel "SessionScopeService" est un service qui doit avoir une portée "session", puisqu'il est appelé simultanément par plusieurs sessions (et pas seulement d'un seul service "firstService"). – silviaB

+0

Étant donné que votre méthode est appelée à partir d'un travail planifié, vous n'aurez jamais une session utilisateur liée au thread, ce qui entraînera l'erreur que vous avez collée dans votre question. Vous devez déplacer votre code dans un autre service situé dans un autre périmètre. – bassmartin