Log in

No account? Create an account
Hijinks Ensue

Java Embedded Scripting Engines

Apologies for the reduced posting frequency; I've started Twittering (under the same user name as I have on LJ), and I'm finding it easier to put any brief thoughts and snippets of news on there than to write a proper journal entry.

I recently put an embedded BeanShell interpreter in ConText so that users can easily add new filters and outputs without needing to first download and set up a development system capable of building ConText. Unfortunately I'm probably going to ditch it because I've encountered a weird bug in the interpreter[1] and the project doesn't seem to be under active development[2]. Which is a bit of a shame because I quite like BS, particularly the fact that it's very lightweight and its syntax is basically the same as Java (with the addition of optional loose typing). Because ConText is written in Java, it would be fairly trivial to prototype a new feature as a BeanShell script and then later add it to ConText as a full-blown Java class. You could also start out writing a new BeanShell script by copying code from the ConText source and modifying it.

When I was younger and more foolish and I ran into bugs in immature compilers/scripting engines, I tended to plough on with them: track down the exact circumstances that trigger the bug, write and submit minimal test cases to the developer(s)[3], and find a workaround so I could continue with my own project until the bug was fixed. Sometimes I even dug into the source of the compiler/interpreter (if it was available) and fixed the bug myself.

One fairly complicated embedded system project took me approximately four times as long as it would have done if the compiler I used had been bug-free. Unfortunately it was the only available compiler for this particular combination of language and processor, and I'd already invested a lot of time in writing code before I realised how buggy the compiler was. It was a language (Forth) that doesn't easily port to other languages, so changing to a compiler for a different language would have meant starting again from scratch. During the development process I kept thinking, "once the latest compiler bug is fixed I will only need to do a little more debugging on my own code and the project will be finished." Then I'd spend another half a day discovering that my program was misbehaving not because of a bug in my code but because the compiler was wrongly optimising away an important bit of logic or emitting a couple of instructions in the wrong order, followed by another half a day reporting the bug and finding a workaround for it. In hindsight it would have taken me significantly less time to have written the project in assembly language, and the experience rather put me off Forth even though the problems I had were the fault of a specific compiler rather than the language itself. That wasn't the only time I ran into compiler/interpreter problems, though it certainly made me much more wary of starting a project that depends on a language implementation that I don't fully trust. Life is too short.

I still want to include an embedded interpreter in ConText though. Any recommendations? Groovy seems popular and it looks fairly simple to embed in an existing application. Like BeanShell its syntax is based on Java but there are enough differences to make porting code back and forth problematic. A disadvantage is that it's not a well-known language so ConText users are unlikely to have encountered it before. Rhino also looks good. It's a Javascript engine developed and maintained by the Mozilla foundation. It actually comes bundled with Sun (Oracle)'s Java SE 6, though currently ConText supports Java 1.5 so I'd still need to bundle it with my application. Jython (Python) and JRuby (Ruby) are possibilities but I suspect they would be quite heavyweight for my purposes.

[1] It has something to do with the class signatures of objects passed into a BeanShell interpreter from the main program - if you pass a reference to an object of class Foo into an untyped variable, you can call methods and access fields in the object but you get a nonsensical class cast exception if you try to assign it to a BeanShell strictly-typed variable of type Foo, and it says it can't find a matching constructor if you try use the variable when instantiating a Java class that takes a Foo object as one of the arguments. I've tried passing the objects into strictly-typed variables instead of loosely-typed but that just gives me an exception along the lines of "Variable assignment: can't assign Foo to Foo". Bah!
[2] It was developed by one guy who seems to have mysteriously abandoned the project in 2005, shortly after going through the process necessary to get it included as a standard part of Java SE. There is a fork called BeanShell2 that looks to be under slightly more active development but it has the same bug.
[3] Often arguing with them that the bug really existed and ought to be fixed.


I avoid Twitter. I prefer reading longer entries.
I understand. I avoided Twitter for a long time, but having tried it I find it convenient for some things.

There are a couple of things on Twitter that I find irritating: the way it handles public conversations - you often only see half of a conversation because you aren't following all of the participants - and people using mobile phone apps to announce their location every five minutes. It's also a bit of a shame that the public/private setting applies to your entire account rather than individual Tweets (I believe a lot of people get around this by having two accounts).
Me too!