检测Scala程序中函数更改的最佳实践?

时间:2011-09-23 15:05:49

标签: java scala bytecode

我正在开发一种基于Scala的脚本语言(内部DSL),允许用户在Scala脚本文件中定义多个数据转换函数。由于这些功能的应用可能需要几个小时,我想将结果缓存在数据库中。 允许用户更改转换函数的定义以及添加新函数。但是,然后用户使用略微修改的脚本重新启动应用程序,我只想执行已更改或添加的那些功能。问题是如何检测这些变化?为简单起见,我们假设用户只能调整脚本文件,以便可以假定对此脚本中未定义的内容的任何引用都保持不变。

在这种情况下,检测此类用户定义函数的更改的最佳做法是什么?

到目前为止我虽然关于:

  • 解析脚本文件并根据函数定义的源代码计算指纹
  • 在运行时获取每个函数的字节码并根据此数据构建指纹
  • 将函数应用于某些测试数据并计算结果上的指纹

但是,这三种方法都存在缺陷。

  • 为Scala编写解析器以提取函数定义可能是相当有用的,特别是如果您想要检测间接影响函数行为的更改(例如,如果您的函数调用脚本中定义的另一个(更改的)函数)
  • 字节码分析可能是另一种选择,但我从未使用过这些库。因此,我不知道他们是否可以解决我的问题以及他们如何处理Java的动态绑定。
  • 使用示例数据的方法绝对是最简单的方法,但缺点是如果不同的用户定义函数为我的测试数据返回相同的结果,则可能会意外地将其映射到同一指纹。

有人对这些“解决方案”中的一种有经验,还是可以建议我做一个更好的解决方案?

1 个答案:

答案 0 :(得分:3)

第二种选择看起来并不困难。例如,使用Javassist库获取方法的字节码就像

一样简单
CtClass c = ClassPool.getDefault().get(className);
for (CtMethod m: c.getDeclaredMethod()) {
    CodeAttribute ca = m.getMethodInfo().getCodeAttribute();
    if (ca != null) { // i.e. if the method is not native
        byte[] byteCode = ca.getCode();
        ...
    }
}

所以,只要你假设你的方法的结果只依赖于那些方法的代码,那就非常直截了当。

<强>更新 另一方面,由于您的方法是用Scala编写的,它们可能包含一些闭包,因此它们的部分代码驻留在匿名类中,您可能需要以某种方式跟踪这些类的使用。