Grails:运行插件时服务未注入控制器

时间:2019-06-07 19:57:18

标签: grails grails-plugin grails-3.3 grails-services

我正在创建一个Grails(3.3.9)插件来保存一些内部应用程序的共享后端代码。出于某种原因,当我运行插件进行测试时,我的服务没有注入到控制器中。

我从默认的Web插件配置文件开始,创建了一个名为Entry的域类,然后运行generate-all创建一个控制器,服务和视图。当我尝试将插件作为应用程序运行并查看单个域实例时,出现以下错误:

Cannot invoke method get() on null object. Stacktrace follows:

java.lang.reflect.InvocationTargetException: null
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: Cannot invoke method get() on null object
    at com.mycompany.internal.EntryController.show(EntryController.groovy:18)
    ... 14 common frames omitted

stacktrace将我带到控制器的第18行:

def show(Long id) {
    respond entryService.get(id)
}

这向我表明entryService为空。

我的域类如下:

class Entry {

    String entryCode
    String description
}

控制器如下:

class EntryController {

    EntryService entryService

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond entryService.list(params), model:[entryCount: entryService.count()]
    }

    def show(Long id) {
        respond entryService.get(id)
    }

    //snipped for brevity

服务看起来像这样:

@Service(Entry)
interface EntryService {

    Entry get(Serializable id)

    //snipped for brevity

}

基于Grails插件文档,我希望能够像其他任何应用程序一样独立运行插件,并且在普通应用程序中,将服务定义为接口可以正常工作。如果我将此插件安装到本地Maven缓存中并在应用程序中使用,则它的工作原理与我期望的完全相同。我可以访问控制器的show端点并从数据库中获取结果。

有一次我尝试将服务实现为类而不是将其作为接口,但是随后出现此错误:

URI
/entry/index
Class
java.lang.IllegalStateException
Message
null
Caused by
Either class [com.mycompany.internal.Entry] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.

关于如何正确设置和运行Grails插件,我缺少什么?

1 个答案:

答案 0 :(得分:0)

最后通过深入研究GORM问题找到了答案:class Authority is not a domain class or GORM has not been initialized correctly or has already been shutdown

显然,问题的根源在于需要向compile "org.grails.plugins:hibernate5"中的dependencies块添加build.gradle。奇怪的是,Web插件配置文件提供了create-domain-class命令,因此我认为默认情况下将包括GORM和Hibernate支持,但是我显然误解了插件应该如何工作的某些方面。 / p>