java - 检测 Scala 程序中函数变化的最佳实践?

标签 java scala bytecode

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

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

到现在为止我在想:

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

然而,这三种方法都有其缺陷。

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

是否有人对这些“解决方案”之一有经验或可以建议我更好的解决方案?

最佳答案

第二个选项看起来并不难。例如,使用 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 编写的,它们可能包含一些闭包,因此它们的部分代码驻留在匿名类中,您可能需要以某种方式跟踪这些类的使用情况。

关于java - 检测 Scala 程序中函数变化的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7531131/

相关文章:

scala - 迭代数据框中的每一行,将其存储在 val 中并作为参数传递给 Spark SQL 查询

scala - 如何更改 play/sbt 下自定义配置的设置值?

java - 在 Java 字节码/类格式中,什么决定一个方法是否覆盖另一个方法?

compilation - 为什么在执行时而不是在安装时编译字节码 JIT?

java - Spring MVC中如何将bean中的数据插入数据库?

java - 用于匹配 Java 中 Pattern 类中的模式的正则表达式

java - 测试类中的模拟接口(interface)

java - 是否可以像 Android SDK 中的 Tree Overview 一样在 android 中创建或制作 Tree Structure View ?

scala - 值 reduceByKey 不是 org.apache.spark.rdd.RDD 的成员

java - ASM字节码: prepending visitMethodInsn with another invocation