Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Enhances Grails Controller

I have a Trait defined like so:

@Enhances(ControllerArtefactHandler.TYPE)
trait NullCheckTrait {
   def nullCheck(def object) {
      // code here
   }
}

When I call nullCheck(foo) from my controller, I get the No signature of method exception. If I implements NullCheckTrait on the controller, it works fine. I've read that @Enhances will only work if I create a grails plugin and put the trait there. I'm curious if this is a known issue and if there is a way to get the @Enhances to work from the same grails application as the controller.

like image 890
Gregg Avatar asked Mar 25 '16 21:03

Gregg


People also ask

What is a controller in grails?

In Grails a controller is a class with a name that ends in the convention "Controller" and lives in the grails-app/controllers directory. A controller can be created with the create-controller command: grails create-controller org.bookstore.hello. or with your favourite IDE or text editor. package org.

Whats new in grails 5?

The Grails Foundation has released Grails 5.0 featuring deprecation of the "dot"-Based Navigation to configuration; default autowire by type in Data Services; the decoupling of Grails Gradle Plugin from the grails-core ; and the removal of the Grails Gradle Publish plugin from the grails-plugin applications.


2 Answers

No there is no way to get around this since @Enhances classes need to be on the classpath before compilation. For example say your controller class is compiled first and then later your trait then the trait won't be applied, and since there is no way to control compilation order this will remain an issue.

The only other way this could be done in the same project is to setup an additional source set in Gradle, see:

How do I add a new sourceset to Gradle?

like image 75
Graeme Rocher Avatar answered Sep 20 '22 18:09

Graeme Rocher


There's one more solution which does not need you to create a custom additional source set.

grails gradle plugin, by default comes with a sourceset named ast which gets compiled before any main sourceset. so you can put your Trait in ast sourceset and that will get applied to artefacts even in the same plugin/project.

Here's how your project structure should be

 src
  +
  +--+ast
        +
        +--+groovy
                 +
                 +--+MyAwsomeTrait.groovy

And this will get compiled before the classes in src/main sourceset and grails will pick your sourceset and apply it.

update: Grails configures the ast sourceset only for plugin projects and not application. Here I wrote a blog entry about how to create an AST sourceset for applications

like image 21
Sudhir N Avatar answered Sep 22 '22 18:09

Sudhir N