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?
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:
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With