When Groovy reached version 2, it gained many new features and improvements in productivity and security. Groovy now supports static type checking and compilation of your Groovy code for robustness and performance. This is very useful when you don’t need Groovy’s dynamic features or simply want to improve the performance of your scripts.
Let’s say, you’re invoking Groovy scripts via GroovyShell within your application. You may want your scripts to be statically compiled to prevent missing properties or methods from being passed to the runtime, or you may just want to speed up your system. For such a purpose, you can make your own extension for Groovy script files, and tell GroovyShell that you want it to statically compile all scripts with that extension.
Take a look at these lines of code:
StaticScript.groovy
class Greeter {
// no methods
}
// Will result in MultipleCompilationException
Greeter.metaClass.greet = { String name -> println "Hello $name!" }
def greeter = new Greeter()
greeter.greet('John')Main.groovy
...
def compilerConfiguration = new CompilerConfiguration()
CompilerCustomizationBuilder.withConfig(compilerConfiguration) {
source(extensions: ['sgroovy']) {
ast(CompileStatic)
}
}
compilerConfiguration.setScriptExtensions(['groovy', 'sgroovy'] as Set<String>)
def groovyShell = new GroovyShell(compilerConfiguration)
...
def script = groovyShell.parse(scriptFile) // parsing script file StaticScript.sgroovy extension
script.run() // running script
...The following lines of code configure GroovyShell’s behavior for files with *.sgroovy extension, so that these scripts will be compiled statically. This means that when you run your scripts with *.sgroovy extension using this modified GroovyShell, any undeclared variable, method, or metaClass extending, etc., will result in MultipleCompilationException at compilation time!
Sometimes you may want your executed scripts to have some predefined methods, properties, classes, or annotations. This can be done by creating an abstract class inherited from the Script class. Assume you want your script to return null instead of throwing a MissingProperty/MissingMethod exception in situations when a property or method doesn’t exist. All you need is to set your custom Script class as a script base superclass in CompilerConfiguration and then apply it to GroovyShell.
Here’s an example of how you can achieve this:
CustomScript.groovy
package org.sysgears.script
abstract class CustomScript extends Script {
// here can go any other stuff (properties, methods, classes, etc.)
def propertyMissing(String name) {
null
}
}Main.groovy
...
def compilerConfiguration = new CompilerConfiguration()
compilerConfiguration.setScriptBaseClass('org.sysgears.script.CustomScript')
def groovyShell = new GroovyShell(compilerConfiguration)
...
Script script = groovyShell.parse(scriptFile) // scriptFile is a Script.groovy script
script.run() // running scriptScript.groovy
println person == null // prints true instead of throwing MissingPropertyExceptionBesides these features, you can do even more: customize imports, secure AST (allow/disallow closure creation, imports, package definition, definition of methods, etc.), and more.
Check out Groovy Official Documentation to stay in touch!
Cheers!
