Anton Hlinisty
Anton Hlinisty

Reputation: 1467

Grails. How to handle the 'mixed' methods and variables when using @GrailsCompileStatic

I'm eager to use the @GrailsCompileStatic annotation in many places of my grails 3.1.7 application. But the main problem is that it doesn't take into account that domains, commands and controllers are 'mixed' with additional methods (like save() or validate()) or variables (like g).

I found a workaround for the mentioned methods: I inherit domains and commands from an abstract class that has an empty save() method (it's implementation is overriden then by grails but static compilation doesn't fail). Also this abstract class implements grails.validation.Validateable trait with validate() method implementation.

But is there any better way to enable static compilation without these dirty tricks?

In many controllers I use the g.createLink() method. How should I pass g variable inside to avoid this during the static compilation?

Error:(37, 39) Groovyc: [Static type checking] - The variable [g] is undeclared.

Upvotes: 0

Views: 219

Answers (2)

Elias Medeiros
Elias Medeiros

Reputation: 395

Complementing what @andi answered, just to add a solution to the g.createLink() issue:
You can inject a LinkGenerator bean and use static compilation as desired.

Note: you'll have to inject the dependency like this:

LinkGenerator grailsLinkGenerator

And import the class from the package grails.web.mapping

Upvotes: 0

andi
andi

Reputation: 361

AFAIK, @GrailsCompileStatic already allows you to use methods like save(). In my case, it is only a problem of the groovy eclipse plugin, while grails run-app works fine.

Anyway, since grails 3, methods provided by traits are accessible by "implementing" the trait directly as documented here

The traits are compatible with static compilation…​

class TestController implements Controller {
        @GrailsCompileStatic
        def index() {
            render "test"
        }
    }

g seems to be of type NamespacedTagDispatcher, which uses methodMissing to find the called method at runtime. Even if you would get compile time access to g, g.createLink() wouldn't compile.

You could extract performance critical code into another method and annotate it with @CompileStatic or write an unannotated method that is calling g.createLink()

Upvotes: 0

Related Questions