grails / grails-data-mapping

GORM - Groovy Object Mapping
http://gorm.grails.org/
218 stars 198 forks source link

Grails-4.0.4: init fails, it can not find services #1366

Closed rawi2 closed 4 years ago

rawi2 commented 4 years ago

I can not start a new test application with version 4.0.4 because init doesn't find the Service. The same with an application, which works on 4.0.3 (developer mode)

Task List

Steps to Reproduce

grails create-app test
cd test
grails create-domain test.Book
## write in grails-app/domain/test/Book.groovy a property eg: String name
grails generate-all test.Book
grails run-app

Expected Behaviour

Application should start

Actual Behaviour

init fails because it can not find the BookService. All the necessary files are in place

Stacktrace


...
: Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bookService': Invocation of init method failed; nested exception is org.grails.datastore.mapping.services.ServiceNotFoundException: No service found for type interface test.BookService
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:841)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
        at test.Application.main(Application.groovy:11)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.grails.datastore.mapping.services.ServiceNotFoundException: No service found for type interface test.BookService
        at org.grails.datastore.mapping.services.DefaultServiceRegistry.getService(DefaultServiceRegistry.groovy:81)
        at org.grails.datastore.mapping.core.AbstractDatastore.getService(AbstractDatastore.java:102)
        at sun.reflect.GeneratedMethodAccessor64.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:280)
        at org.springframework.beans.factory.config.MethodInvokingBean.invokeWithTargetException(MethodInvokingBean.java:123)
        at org.grails.datastore.mapping.config.DatastoreServiceMethodInvokingFactoryBean.invokeWithTargetException(DatastoreServiceMethodInvokingFactoryBean.groovy:30)
        at org.springframework.beans.factory.config.MethodInvokingFactoryBean.afterPropertiesSet(MethodInvokingFactoryBean.java:108)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1830)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1767)
        ... 22 common frames omitted

Environment Information

$ lsb_release  -a
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.6 LTS
Release:        14.04
Codename:       trusty
$ uname -a
Linux hg1-9004-2 3.13.0-170-generic grails/grails-core#220-Ubuntu SMP Thu May 9 12:40:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

- **JDK Version:**

$ java -version java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)


### Example Application

Standard New Application with a Domain Class test.Book and all automatically generated Controller, Service, Views etc

package test class Book { String name static constraints = { } }



### Thank you for all, love Grails :-)
puneetbehl commented 4 years ago

I am debugging the issue. Meanwhile, you could workaround the problem by removing the following dependency:

 developmentOnly("org.springframework.boot:spring-boot-devtools")
rawi2 commented 4 years ago

Thank you very much puneetbehl. It starts this way. I'm experiencing a problem after changes in Controllers in developer mode: Though a change and recompiling would be noted on the console, the change wouldn't be active and used until I stop Grails and run-app again. To long to wait, to really enjoy... Could this be a side effect of removing the one dependency you mentioned above?

puneetbehl commented 4 years ago

Yes, there is some issue when the interface reloads because the Class<?> interfaceType reference value is different from the one in the servicesByInterface Map here: https://github.com/grails/grails-data-mapping/blob/master/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/services/DefaultServiceRegistry.groovy#L79

Right now, I am trying to focus on Grails 4.1.0 with Groovy 3 but I would need to check why it is failing now vs 4.0.3.

puneetbehl commented 4 years ago

The reloading would not work once you remove the above dependency.

rawi2 commented 4 years ago

I understand that Grails 4.1.0 is a more important step. Sorry that this issue is no more "in progress". I'll go back to 4.0.3. Thanks again and I wish you much success with 4.1.0

puneetbehl commented 4 years ago

This needs to be fixed before 4.1.0 as it would be the problem in that too. However, I am in middle of something at the moment and would look at it once I am done with the same.

Please feel free to send a PR if you could track and fix the problem.

pjdvmalan commented 4 years ago

Given the severity and expected delay in a fix, would it not make sense to remove 4.0.4 at this point in time?

rawi2 commented 4 years ago

Thank you all for looking into this issue. I'm not in your professional league and I don't understand what's going behind the curtains. I kept the 4.0.4 install and reverted only the dependencies of an application to the ones of 4.0.3 and it works this way; despite having 4.0.4 installed and grailsVersion=4.0.3 in gradle.properties

puneetbehl commented 4 years ago

A potential fix would be to change the serviceMap and servicesByInterface key to a fully qualified class name instead of Class in the following:

https://github.com/grails/grails-data-mapping/blob/7.0.x/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/services/DefaultServiceRegistry.groovy#L37

Also, you need to update the following implementation of def <T> T getService(Class<T> interfaceType) throws ServiceNotFoundException as following:

  @Override
    def <T> T getService(Class<T> interfaceType) throws ServiceNotFoundException {
        Service s = servicesByInterface.get(interfaceType.getName())
        if(s == null) {
            throw new ServiceNotFoundException("No service found for type $interfaceType")
        }
        return (T) s
    }
jeffscottbrown commented 4 years ago

would it not make sense to remove 4.0.4 at this point in time?

No, I do not think it makes sense to remove 4.0.4 at this point in time.

jnunderwood commented 4 years ago

Is there a work-around until the next version of Grails is released? Thanks.

puneetbehl commented 4 years ago

Please update gorm.version property in gradle.properties to 7.0.7

jnunderwood commented 4 years ago

I tried that once and it didn't change anything.

chrisbrookes commented 4 years ago

Changing gormVersion property in gradle.properties didn't work (by itself) for me either but the following seems to work around the issue:

In build.gradle, dependencies block:

    compile "org.grails:grails-datastore-core:$gormVersion"
    compile "org.grails:grails-datastore-gorm:$gormVersion"
    compile "org.grails:grails-datastore-gorm-support:$gormVersion"
    compile "org.grails:grails-datastore-gorm-test:$gormVersion"
    compile "org.grails:grails-datastore-gorm-validation:$gormVersion"
    compile "org.grails:grails-datastore-web:$gormVersion"

(make sure gormVersion is 7.0.7.RELEASE in gradle.properties)

puneetbehl commented 4 years ago

@chrisbrookes It shouold be gorm.version.

chrisbrookes commented 4 years ago

@puneetbehl Thanks, that works. There was confusion because grails create-app creates a skeleton app that has the following in the gradle.properties:

grailsVersion=4.0.4
gormVersion=7.0.6.RELEASE

i.e. gormVersion not gorm.version.

puneetbehl commented 4 years ago

Right, I think property gormVersion is used in build.gradle whereas gorm.version is used to update the GORM version via BOM. See the following:

https://github.com/grails/grails-core/blob/v4.0.4/build.gradle#L60