Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PostConstruct fails silently on a Grails Service

I thought the Spring annotations were supposed to work out of the box in a Grails environment, but I cannot get it to work at all. I also tried the afterProperties method, which did not work either.

Can anyone spot a mistake? Is there some configuration I need to do?

package dashboard

import javax.annotation.PostConstruct

class EmailJobSchedulerService
{
    def grailsApplication

    @PostConstruct
    def init() {
        def cronExpression = grailsApplication.config.emailAt8AmTrigger
        println(cronExpression)
        EmailSubscribersJob.schedule(cronExpression, new HashMap())
    }
}
like image 964
willcodejavaforfood Avatar asked Feb 12 '13 11:02

willcodejavaforfood


2 Answers

Try changing it to

@PostConstruct
void init() {

(i.e. void instead of def). I'm not sure whether Spring specifically enforces this but the specification of @PostConstruct states that among other things "The return type of the method MUST be void".

Edit: uchamp's comment is correct, I just tried the same test and indeed the @PostConstruct annotated method is called only the first time the service bean is used and, not necessarily immediately at startup. You can add

static lazyInit = false

to the service class to force it to be initialized eagerly at startup. This doesn't appear to be documented in the user guide, I deduced it by reading the code.

Note that "used" in the previous paragraph doesn't necessarily mean you have to call a method on it. The service bean will be initialized the first time it is fetched from the application context, either directly or because it has been autowired into another bean that is being initialized. For example, injecting the service into BootStrap using

def emailJobSchedulerService

would be enough to fire the @PostConstruct method, you don't have to actually call any of the service's methods from the BootStrap.init closure. Similarly, if your service were injected into any controllers then the init would fire the first time one of those controllers handled a request (any request, it doesn't have to be an action that calls the service).

like image 186
Ian Roberts Avatar answered Nov 03 '22 16:11

Ian Roberts


Just adding on the answer from @Ian - For some reason i had:

@PostConstruct
private void init() {

This also failed silently and gave strange behavior. Solution was to remove "private":

@PostConstruct
void init() {
like image 31
Svante Avatar answered Nov 03 '22 17:11

Svante