使用Lisp或Scheme对Java程序进行运行时配置 [英] Using Lisp or Scheme for runtime configuration of Java programs

查看:126
本文介绍了使用Lisp或Scheme对Java程序进行运行时配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在看到几个项目以实际配置取决于仅在运行时可用的事物结束.

配置Java程序的典型方法是根据一些特定于应用程序的规则读取一个或多个属性文件,然后根据其值采取措施.在某一点或另一点发生故障,您需要在配置中使用实际的程序逻辑,然后可以使用标志来指示该逻辑,并向应用程序中添加代码,然后处理该标志.

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

我对具有钟声和口哨声的完整Lisp引擎不感兴趣,但对于为此目的只是一个小型库,即使没有小型程序,也可以将其封装在很小的程序中,而无需装有Lisp引擎的大罐子.

>

那么这样的图书馆存在吗?

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

建议?


编辑2012-01-20:我最初发现所有候选人都不理想,但已决定将此作为 https://github.com/ravn/jscheme-1998


Edit 2012-12-11:原来,我最初认为,在Scheme中解释的程序与Java宿主程序之间的 integration 层更为重要,而在该项目能够在运行时提供带有JAX-WS注释的类,而我无法使用JScheme,但可以使用Groovy.允许在库中使用代码片段的小型配置库的想法仍然有效,但是我最终需要更多配置才有用.

解决方案

我知道您想要小巧的体积和运行时间. Scheme是易于嵌入的通常选择,它将是我的首选.但是,我没有关于该领域的信息.我的第二个选择是 Clojure :

  • 不算小;罐子大约是3 MB
  • 对于简单的配置读取会产生过多的杀伤力,但是可以安全地忽略额外的功能
  • 〜易于从Java调用:从Java调用clojure
  • 全面,出色的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编译脚本会带来很大的损失!

I have now seen several projects ending at a point where the actual configuration depended on things only available at run-time.

The typical way to configure a Java program is to read one or more property files according to some application specific rules and then take action depending on their values. At one point or another this breaks down and you need actual program logic in your configuration which then can be indicated with a flag and adding code to your application which then handles the flag.

I was wondering if a tiny Lisp configuration reader module might be a better option, where the file to be read is not a property file but a Lisp program which is then eval'ed to create a final datastructure representing the configuration. A minimal set of functions in the runtime library would then allow string manipulation and perhaps even calling into the JVM. Just think of "construct an URL based on the current hostname".

I am not interested in a full Lisp engine with bells and whistles but just a small library for this purpose which can be enclosed in even small programs without a large jar containing the Lisp engine.

So does such a library exist?

  • Small size
  • Just need read file + eval and the ability to read the resulting data structure from the main Java program
  • A small Lisp runtime library
  • Speed is of lesser importance.
  • Actively maintained.

Suggestions?


Edit 2012-01-20: I initially found all the candidates undesirable, but have decided to use this as a Maven exercise on the side with the 1998 jscheme 1.4 release. Project at https://github.com/ravn/jscheme-1998


Edit 2012-12-11: It turned out that the integration layer between the program being interpreted in Scheme and the host Java program was more important that I originally thought, and that I needed in a project to be able to provide classes with JAX-WS annotaions at runtime, which I could not do with JScheme but I could do with Groovy. The idea of a small configuration library which allows code snippets in the libraries is still valid, but I ended up needing more for it to be useful.

解决方案

I know you want a small size and runtime. Scheme is the usual choice for easy embedding, and would be my first choice. But I have no information on that field, though. My second choice is Clojure:

  • Not that small; the jar is ~3 MB
  • Overkill for a simple config reading, but the extra features can be safely ignored
  • ~ Easy to call from Java: Calling clojure from java
  • Full, excellent access to JVM
  • Might invoke a small extra to the startup, which can be too much (see below)
  • Now that I tried replicating the example's functionality with Clojure, I feel that Clojure isn't well suited for these kind of scripts (rc, etc). Clojure 1.3 will address some of that startup penalty but I don't know the magnitude of speed improvements coming

A respective code with using 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));
    }
}

with hello.clj being:

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

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

Running time java ClojTest for a while yields in an average of 0.75 seconds. Clojure compiling the script has quite a penalty!

这篇关于使用Lisp或Scheme对Java程序进行运行时配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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