编译用户在运行时输入的 groovy 脚本 [英] Compiling user entered groovy script at run time
问题描述
有一个如下场景,我需要验证 groovy 脚本的正确性.
Have a scenario as below where I need to validate the groovy script for correctness.
class CostCalculator{
String name
String groovyScript
static constraints = {
groovyScript:static validateScript = {String script ,def obj->
boolean status = true
try {
def shell = new GroovyShell()
def data = shell.parse(script)
data.run()
}catch (Throwable e){
e.printStackTrace()
status = false
}
if(!status){
return "domain.script.compilation.errors"
}else{
return true
}
}
}
}
上面代码的问题在于它运行代码,如果有任何异常,它会在运行时抛出它.
Problem in above code is that it runs the code and if there is any exception it throws it at runtime.
有几点需要考虑:
- groovy 代码应该编译而不是运行(因为代码可能包含数据库级别的更新)并抛出异常.
- groovy 代码应该静态编译,例如,如果我们在脚本中缺少某些属性,那么它必须得到通知.
下面可能是示例脚本:
void addCost(int x, int y,String itemName){
double cost = x*y + originalCost
Item item = SoldItem.findByItemName(itemName)
item.price += cost
}
推荐答案
我建议将您的 groovy 脚本放在一个类中.
I would recommend to put your groovy script in a class.
在示例中,您有方法 addCost(),所以我想说只需将此方法包装在一个类中即可.例如:
In the example you have method addCost(), so I would say just wrap this method in a class. ex:
String gScript = """
class CostCalculatorScript{
void addCost(int x, int y,String itemName){
double cost = x*y + originalCost
Item item = SoldItem.findByItemName(itemName)
item.price += cost
}
}
"""
现在使用 GroovyClassLoader 加载和解析这个脚本.
Now load and parse this script using GroovyClassLoader.
ClassLoader gcl = new GroovyClassLoader()
Class clazz = gcl.parseClass(gScript)
验证加载的类是否与您在脚本中指定的名称相同.
Verify that the loaded class have the same name as you have specified in your script.
assert clazz.simpleName == 'CostCalculatorScript'
现在你想要的那种解决方案看起来像静态编译.您可以将 @groovy.transform.CompileStatic 注释添加到您的类中.但是这个注释的问题是你不能使用 grails 的动态查找器或 def 关键字.
Now the kind of solution you want does seem like static compilation. You can add the @groovy.transform.CompileStatic annotation to your class. But with this annotation the problem is that you can't use the dynamic finders of grails or the def keyword.
但是如果您仍然想要该功能,那么您应该使用 @grails.compiler.GrailsCompileStatic 注释,在 Grails 2.4 中可用.
But if you still want that functionality then you should use @grails.compiler.GrailsCompileStatic annotation which is available in Grails 2.4.
这篇关于编译用户在运行时输入的 groovy 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!