Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Lisp or Scheme for runtime configuration of Java programs

Tags:

java

lisp

scheme

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.

like image 518
Thorbjørn Ravn Andersen Avatar asked May 28 '11 09:05

Thorbjørn Ravn Andersen


2 Answers

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!

like image 122
mike3996 Avatar answered Nov 02 '22 18:11

mike3996


Try SISC, it is a reasonably small (300kb jar) Scheme implementation with no bells and whistles. Glueing it with Java is trivial, and an execution speed is quite impressive for a pure interpreter.

like image 6
SK-logic Avatar answered Nov 02 '22 16:11

SK-logic