编译用户在运行时输入的 groovy 脚本 [英] Compiling user entered groovy script at run time

查看:20
本文介绍了编译用户在运行时输入的 groovy 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个如下场景,我需要验证 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.

有几点需要考虑:

  1. groovy 代码应该编译而不是运行(因为代码可能包含数据库级别的更新)并抛出异常.
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆