Search code examples
grailsenvironmentstatic-compilation

How to set static compilation in Grails?


I'm beginner with Grails and I want to use a static compilation, but I don't want to use GrailsCompileStatic annotation for each class. Can I set it up for all classes in the configuration files?

The GrailsCompileStatic annotation can't be used, because I need use a static compilation just for production environment. For other environments should be used dynamic compilation.

Does anyone know a solution, please?? And how can I verify the used compilation?

Thanks for answers..


Solution

  • You don't want static compilation globally. It seems that you don't understand what @CompileStatic does since you want it active in dev but not prod. It has all of the features of @TypeChecked, so the compiler is as aggressive as the Java compiler. This sounds good because it will catch typos and other errors at compile time instead of at runtime when using traditional Groovy. That does happen, but you lose a lot of functionality also.

    In addition to using the strict type checker, @CompileStatic disables all dynamic Groovy features. This is basically everything that cannot be known to be correct at compile time. It doesn't affect syntactic sugar features like list comprehensions (def foo = [1, 2, 5]) because that's essentially a replacement for creating a new ArrayList and adding the items to it, so it's clear that it's valid.

    You'll also find that many plugins are unusable because they use dynamic Groovy features, and the code wouldn't compile in your application. That could be a positive however; your team will learn a lot more about Grails than otherwise because they'll have to reinvent so many wheels ;)

    But you'll lose a lot of the GORM methods, in particular the dynamic finders. Many GORM methods are not dynamic, so they're added by AST transformations, but User.findAllByAgeAndGender(...) is dynamic because it would be too expensive to figure out all of the combinations at startup.

    So you'll have to be very careful about what is safe to use in dev mode and what's not, because if someone forgets and uses a dynamic method you won't know that this happened until some user hits that code path in production.

    Static type checking and compilation are great features to have in Groovy, but using them for 100% of your code in a Grails app will have a significantly lower increase in performance than I assume you're expecting. If you look at the total time it takes to complete a web request to your server and back to the client, there are a lot of factors. DNS lookups and network speed take up a lot of the time, and for most applications the majority of request time is spent waiting for database queries and updates to run. The total time that Grails/Groovy code spends doing work is going to be rather low, and it's only part of the non-database time spent at the server. The rest of that time is in Grails code, which is written in Java or Groovy (a mix of with @CompileStatic and dynamic), and in the Spring and other 3rd-party libraries. If Groovy code accounts for 20% of the time (I doubt it's that high on average) and you're able to make that code run twice as fast with @CompileStatic then you will have cut that 20% to ~10%. Yes it's faster, but unlikely to be noticeably faster, and you'll have made your work far less fun because you'll be constantly frustrated with what you should be able to do but cannot.

    If you are willing to give up that much, perhaps Grails isn't the best choice.