【问题标题】:Using Lisp or Scheme for runtime configuration of Java programs使用 Lisp 或 Scheme 进行 Java 程序的运行时配置
【发布时间】:2011-09-03 21:08:10
【问题描述】:

我现在已经看到几个项目在实际配置依赖于仅在运行时可用的东西时结束。

配置 Java 程序的典型方法是根据某些特定于应用程序的规则读取一个或多个属性文件,然后根据它们的值采取行动。有时这会发生故障,您需要在配置中使用实际的程序逻辑,然后可以用标志指示并将代码添加到您的应用程序,然后处理该标志。

我想知道小型 Lisp 配置阅读器模块是否是更好的选择,其中要读取的文件不是属性文件,而是 Lisp 程序,然后评估该程序以创建代表配置的最终数据结构。然后,运行时库中的最小函数集将允许字符串操作,甚至可能调用 JVM。想想“根据当前主机名构造一个 URL”。

对带有花里胡哨的完整 Lisp 引擎感兴趣,而只是为此目的的一个小型库,即使没有包含 Lisp 引擎的大 jar,也可以将其封装在小程序中。 p>

那么这样的库存在吗?

  • 体积小
  • 只需要读取文件 + eval 以及从 Java 主程序读取结果数据结构的能力
  • 一个小型 Lisp 运行时库
  • 速度不太重要。
  • 积极维护。

建议?


编辑 2012-01-20:我最初发现所有候选人都不受欢迎,但决定将其用作与 the 1998 jscheme 1.4 release 一起的 Maven 练习。项目https://github.com/ravn/jscheme-1998


Edit 2012-12-11: 结果发现,在 Scheme 中解释的程序和宿主 Java 程序之间的 集成 层比我最初认为的更重要,我需要在一个项目能够在运行时为类提供带有 JAX-WS 注释的类,我不能用 JScheme 做,但我可以用 Groovy 做。允许在库中使用代码 sn-ps 的小型配置库的想法仍然有效,但我最终需要更多才能使其有用。

【问题讨论】:

  • 您是否想过将JavaScript 与JSON 结合使用?这会给你脚本和binding JSON 到 Java 类型会相对容易。 如果您不知道目标 JRE,请注意有 pitfalls
  • @McDowell,我认为 JavaScript 在许多支持 JSR-233 的 JVM 中默认提供,但正如您所说,它不是普遍可用的,所以我需要随身携带。我相信一个小的 Lisp 评估器应该更小。
  • @McDowell 我的目标 JVM 已经包含了一个 JavaScript 引擎,所以这不再是问题了。然而,我现在有另一份工作:)

标签: java lisp scheme


【解决方案1】:

好的,更小的解决方案是 Java 的嵌入式方案。在许多实现中,我找到并测试了JScheme。 (API 看起来不错:http://jscheme.sourceforge.net/jscheme/doc/api/index.html

一个简单的Java主程序:

import jscheme.JScheme;
import jscheme.SchemeException;
import java.io.*;
public class SchemeTest {
    public static void main(String[] args) {
        JScheme js = null;
        try {
            js = new JScheme();
            js.load(new FileReader("config.scm"));
        } catch (FileNotFoundException e) { return; }

        System.out.println("Message: '" + js.eval("msg") + "'");

        // Values
        int answer = (Integer) js.eval("answer");

        // Function calls
        System.out.println(js.call("countdown", 42));
    }
}

还有一个例子config.scm

(define (countdown x)
  (define (loop x acc)
    (if (= x 0)
      acc
      (loop (- x 1) (+ acc x))))
  (loop x 0))

;;; config variables
(define msg "Hello from JScheme!")
;; tail calls are optimized as required
(define answer (countdown 42))

每次启动时都会解释该方案,因此这是配置的不错选择。 JScheme 的优势包括:

  • 良好的 JVM 集成
  • 显然是一个完整的 Scheme 实现
  • 小尺寸 (572 kB)
  • 快速,从 Java 中调用有点容易

基准更新:此代码在 0.13 秒 时间内运行。与 Clojure 版本的时间相比,这相当快。

【讨论】:

  • 我会看看方案精简版的东西。
  • 我查看了 7.2 下载,但找不到您所说的 lite jar。你在哪里看到的?
  • @Thorbjørn:它在 Gentoo 中随包一起提供。对不起——我应该早点检查它,因为它什么都没有。 :(
  • 原来 jschemelite.jar 只包含 build/SchemeLite.java,它只是从 URLClassLoader 中的 sourceforge 下载 jscheme.jar 文件并调用 main 方法。跟我想的不太一样。
  • 另外,开发活动看起来非常低:-(
【解决方案2】:

我知道您想要小尺寸和运行时间。 Scheme 是易于嵌入的常用选择,也是我的首选。但是我没有关于那个领域的信息。我的第二个选择是Clojure

  • 没那么小; jar 是 ~3 MB
  • 简单的配置读取有点过头了,但可以安全地忽略额外的功能
  • ~ 易于从 Java 调用:Calling clojure from java
  • 对 JVM 的完全、出色的访问
  • 可能会在启动时调用一些额外的东西,这可能太多了(见下文)
  • 现在我尝试使用 Clojure 复制示例的功能,我觉得 Clojure 不太适合此类脚本(rc 等)。 Clojure 1.3 将解决一些启动问题,但我不知道未来速度改进的幅度

使用 Clojure 的相应代码

import clojure.lang.RT;
import clojure.lang.Var;
import clojure.lang.Compiler;
import java.io.FileReader;
import java.io.FileNotFoundException;

public class ClojTest {
    public static void main(String[] args) throws Exception {
        try {
            Compiler.load(new FileReader("hello.clj"));
        } catch(FileNotFoundException e) { return; }

        System.out.println("Message: '"+ RT.var("user", "msg").get() +"'");

        // Values
        int answer = (Integer) RT.var("user", "answer").get();

        // Function calls
        System.out.println(RT.var("user", "countdown").invoke(42));
    }
}

hello.clj 是:

(ns user)
(defn countdown [n]
  (reduce + (range 1 (inc n))))

(def msg "Hello from Clojure!")
(def answer (countdown 42))

运行time java ClojTest 一段时间平均产生0.75 秒。Clojure 编译脚本有相当大的惩罚!

【讨论】:

  • 3 Mb 比我认为的“读取配置文件”模块应该是方式。不过,我听说过很多关于 Clojure 的好消息。
【解决方案3】:

试试SISC,它是一个相当小的(300kb jar)Scheme 实现,没有花里胡哨。将它与 Java 粘合起来很简单,而且执行速度对于纯解释器来说是相当可观的。

【讨论】:

    【解决方案4】:

    Clojure 非常出色,它是可嵌入的,并且在调用 Java 库时具有很好的互操作性。然而它并不是特别小(你得到了一个完整的编译器和一个相当不错的运行时库)。如果您对这种功能有更广泛的要求,仍然值得考虑 - 我发现 Clojure 可以作为 Java 代码的出色动态“粘合剂”。

    否则,您最好的选择可能是一个微型嵌入式 Scheme 解释器。

    在这个链接上可能可以使用早期(1998)版本的 JScheme,它只有大约 30k 的 jar 文件: http://norvig.com/jscheme.html

    否则,可能用几百行 Java 写一些更简单的东西......考虑到 Scheme 的核心有多小,这可能只是一个周末项目。如果你想为 Scheme 编写一个迷你解释器,下面的页面非常有趣: http://archives.evergreen.edu/webpages/curricular/2000-2001/fofc00/eval.html

    【讨论】:

    • 我更愿意为此使用维护的库,而不是把东西拼凑在一起 mysefl。
    • 已更新 - 您可能想要 1998 版的 JScheme?
    • 谢谢。我来看看 1998 JScheme。
    猜你喜欢
    • 2010-11-19
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多