Fuzzy writes about the work we're doing...
We beat our rules module into submission.We're writing FIT tests in our Confluence wiki. A custom FIT runner grabs the tests using some specified label and the Confluence XML-RPC api.
As Mike writes, the Javaspaces and JBoss Rules came together well. When I had looked at Drools some time ago I was turned off by its XML nature. Jess is not free, but not expensive, and has good Java integration. Jess also has a good scripting language in its own right (Lisp-based). Back then it would have been a no-brainer.
Since JBoss took on Drools they now have all but done away with XML. In fact none is required from what we've found so far. The Java integration and the rules language itself is not as good as Jess, but it is pretty good and it's free and open.
We've not tried the decision table mechanism. If we're lucky that takes care of most of the Java integration ugliness and if we're *really* lucky our business analyst can use it in whole or in part with little or no programmer intervention. She's very smart, but non-technical. That's the aim of the decision table, I believe. The Jboss site also has something on FIT and JBoss Rules, but we've not tried that yet either. Our FIT tests go through our own fixtures.
On the spaces side we dynamically update and make available all kinds of reference data and object prototypes via a space. When it came time for rules, we did the same thing. Rules are compiled and tested in the build scripts, and stashed away as release artifacts. When the environment is initialized the compiled bytes are sucked out of the files, wrapped in a RulesEntry and written to a space. The rules compiler has all kinds of dependencies but the compiled rules at runtime just depend on one core jar.
We have a mini-grid of sorts that run any kind of TaskEntry.execute() from a space. If such a task happens to need a rules engine, it makes one,
takes *reads* (rules are shared, and so, read, not taken) the appropriate RulesEntry from the space, and squirts the bytes into the rule base. If the rules need to be updated then the new bytes in a new RulesEntry simply replace the old bytes in the old RulesEntry. The next time a task tries to read the entry, it gets the new rules. The TaskEntry objects and code can be updated the same way, no worrying about what is or isn't on some arbitrary JVM's classpath.
The "facts" needed by the task also come from a space. The task takes them from a space and assertObject(entry)'s them into the rule engine's working memory.
The "many, flat" nature of entry objects flowing through spaces and the ease of writing rules around "several, flat" facts makes these two mechanisms the good fit Mike describes.
I will repeat: in my experience, Jini and Javaspaces make Java applications as close to a concurrent, distributed, dynamic system experience as can be done. If you would like to use Erlang, but have to use Java, then try using Jini and Javaspaces.
We're just getting started with this experiment, but everyone's seeing the advantages over even the relatively flexible JMS products.