Search code examples
grailsgroovygrails-orm

Grails: Fetch domain object from service init method


I have created a service where in its init method it tries to load an object from the database, but this error is thrown:

Caused by IllegalStateException: Method on class [pruebainitservice.Conf] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
->>   15 | init      in pruebainitservice.ConfService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|    262 | run       in java.util.concurrent.FutureTask
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run       in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run . . . in java.lang.Thread
| Error Forked Grails VM exited with error

I have created an example project, that basically does this; it just contains a domain class, a service, a controller with an action and its view. You can download from here https://github.com/okelet/grails-test-service-init.

Does anyone know why this happens?

Grails version: 2.3.8 Groovy Version: 2.1.8 JVM: 1.7.0_55 Vendor: Oracle Corporation OS: Linux

Regards and thanks in advance.


Solution

  • looks like @PostConstruct annotation is using it's own ClassLoader, hence the exception.

    I'd use InitializingBean interface to do the init you need:

    class SomeService implements InitializingBean {
    
      @Override
      void afterPropertiesSet() throws Exception {
        doStuffHere()
      }
    }
    

    UPDATE:

    the only solution I could find was to call the init-method from BootStrap:

    class SomeService {
    
      void init(){
        log.debug("Cargando configuración...")
        def confs = Conf.findAll()
         // the rest
      }
    }
    

    and

    class BootStrap {
    
      def confService
    
        def init = { servletContext ->
          confService.init()
        }
        def destroy = {
        }
    }