Controller @Mixin just works after recompile of running app

跟風遠走 提交于 2019-12-13 12:07:01

问题


Within my latest grails 2.3.0 project I'm using the @Mixin annotation to mixin a helper class to keep my controller more DRY.

The mixin is just working if a made some changes within the controller to force a recompile of the controller. After the initial compile (grails run-app) the helper isn't mixed in - I get a MissingMethodException trying to access a method from the helper class.

Here is my helper witin src/groovy:

class ProjectHelper {
    def withProject(id, Closure c) {
        def project = Project.get(id)
        if (project) {
            c.call project
        } else {
            flash.message = 'Project not found!'
            render view: 'myView'
            return
        }
    }
}

And (one of) the controller which uses the ProjectHelper:

@Mixin(ProjectHelper)
class ProjectController {
    def index() {
        withProject params.projectId, {project ->
            // do something with the project
        }
    }
}

When I cleane the project using grails clean and starting the app, I get the following error after accessing project/index:

MissingMethodException occurred when processing request: 
    [GET] /<myApp>/project/
    No signature of method: <myPackage>.withProject() is applicable for argument types: 
    (java.lang.String, <myPackage>.ProjectController$_index_closure1_closure10) values: 
    [1, <myPackage>.ProjectController$_index_closure1_closure10@40d889b5]

After some changes in ReportController (e.g. adding a single space) grails compiles 2 source files and the method withProject could be used. Accessing project/index works as expected.

What's going wrong here? Is it a bug or do I miss something?

Update

It turns out that I totally missed, that using the grails.util.Mixin gives me another exception (MissingPropertyException) due to missing access to the mixed in class properties (in my case: flash) (see JIRA this issue) which is working with groovy.lang.Mixin (after recompile).

Is there a way to manually recompile/inject/mixin the groovy.lang.Mixin at runtime or do I have to find another error handling for the else part till the issue is fixed?

Any suggestions?


回答1:


I had been regularly running into the same MissingMethodException when following a similar code reuse pattern using mixins.

In my case, changing groovy.lang.Mixin to grails.util.Mixin (or more specifically, adding an import for grails.util.Mixin to my controller) resolved the issue completely.

As for not having access to the controller variables, you may be stuck waiting for GRAILS-9905 to be resolved. I should note that there are some suggested work-arounds listed on the defect discussion, though.




回答2:


The workaround that finally worked for me was to manually injecting the Mixin in the Controller constructor:

import com.example.MyMixin

class SomethingController {
  def SomethingController() {
    SomethingController.metaClass.mixin(MyMixin)
  }
}


来源:https://stackoverflow.com/questions/18991513/controller-mixin-just-works-after-recompile-of-running-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!