Monday, December 11, 2006

Free all day JBoss Rules BOF in London

I'm looking to do a free all day BOF in London, potentially Thursday 11th of January, 9.30 to 4.30 - with after session drinks, for those that want to chat some more over a beer and maybe some food? This will be an informal day for those with existing understandings of jboss rules, (we won't be explaining what a working memory is) and want to know more and also find out about whats coming up in 3.2 and we can all share our experiences and of course you can pump the core developers with hard Qs. We would love for volunteers to take 20-30 minutes to casually present their own projects and problems they have solved with jbrules, let me know if you are interested. Ideally I'd like to get between 10 and 20 people, please email me if you are interested. Micheal is leaving to go back to Australia mid january, so ideally it will be before then.

Mark
JBoss Rules Project Lead

Sunday, December 10, 2006

Dynamically Generated Classes as JBoss Rules Facts (Edson Tirelli)

As most users know, JBoss Rules is designed to use standard POJO JavaBeans as facts. This design directive intends, among other things, to:

  • make integration faster: as there is no need to replicate your Business Model in an engine proprietary business model
  • improve performance: as the engine is design to work as optimized as possible when running over the POJO beans. Also, no need to copy attribute values between mapped structures.

In real world, though, supporting POJO beans may not be enough to achieve above goals.

As we all know, Java, as a platform, provides several ways of developing applications that put dynamic resources at good use. And this is using both platform standard features and a whole lot of tools out there in the internet, both open and proprietary.

For instance, we often are asked about "How to use dynamically generated class' beans as facts?". This usually happens in companies that create applications that allow users to define part or the whole of the business model without touching java code. These applications usually have an embedded rules engine, and you may want the engine to reason over these dynamically generated business models.

And the good news is: you can do that with JBoss Rules, and 3.0.5 made it even easier!

The only issue is to make sure you are using a tool to generate your beans that will truly generate standard JavaBeans. I mean, a tool that:

  1. allows you to state specifically what is the package and class name for the generated class: this is mandatory in order to write efficient rules, as the first constraint the engine will apply over your facts are the class type of the facts your rules will reason over
  2. generates a no-argument default constructor (as per the JavaBeans spec)
  3. correctly generates the getXXX() methods for your properties (as per the JavaBeans spec)
  4. ideally will allow you to define what are your bean's key properties and will automatically generate equals()/hashCode() methods for it using these properties (allowing for consistent reasoning based on equality instead of only identity)
  5. ideally will generate fast accessors for your properties, allowing your beans to be high performing

Most bean generation tools will allow that. Just to name a few open source tools (it is not intended to be a full list):

  • ASM: this is by far my preferred framework. I bit lower level than other tools, but allows you to do anything you want (you are writing bytecode after all), and it is as fast as one can be (from my experience).
  • BCEL: another popular framework from Apache.
  • CGLIB: a higher level framework that is used in a lot of projects.

Above frameworks allows you to create a dynamic POJO JavaBean Business Model and use it as your rules business model. Above is just a small list and I'm sure there are a lot of frameworks out there that allow you to do it.

Unfortunately, one also popular framework that fails to work well with JBoss Rules is Apache DynaBeans.
I'm not saying that DynaBeans are bad to all, as there are some use cases for it described in its documentation. What I'm saying is simply that DynaBeans are bad for integration with JBoss Rules. You can read more about it in Mark's post.

So, you have your Business Model (that happens to be dynamically generated), that complies at least with requirements 1-3 listed above, and you want to use it when writing business rules. What you need to do?

You simply must make your business model available for the engine. JBoss Rules will need your classes in 2 distinct situations, that may occur in sequence or not:

  1. Rules compilation
  2. Rules execution

Let’s talk about how to use them in each of the above steps.

It is important to note that all this is closely related to how Class Loaders work in the Java platform, but since you are using dynamically generated classes, I assume you have knowledge of java Class Loader architecture.

1. Rules Compilation

When you write a rules file, whatever the format you use (DRL, DSL, Decision Tables), JBoss Rules needs to compile it before using. When compiling a rule base, the classes you use as facts must be "available".

For instance, if you write a rule base like this:

package org.drools.sample;

import org.drools.sample.facts.Person;
import org.drools.sample.facts.Cheese;

rule "Likes Cheese"
when
Person( $likes : likes )
Cheese( type == $likes )
then
// do some stuff
end


You must have classes Person and Cheese "available" for compilation. The concept of "available" varies though according to the compiler you are using. Also, Person or Cheese or even both classes may be dynamically generated classes. The engine does not care about it, but the compiler certainly does.

JBoss Rules uses JCI (Java Compiler Interface) as an abstraction layer for the compiler layer. JBoss Rules is integrated and tested with two underling compilers: JDT (default) and JANINO.

They will generate the same results, but from a compilation requirements perspective, they are a bit different, so let’s talk about how to make compilation works with each of them.

1.1. Janino

Janino
is not the default compiler for JBoss Rules but you can activate it either by using a PackageBuilderConfiguration.setCompiler() method or by setting the "drools.compiler=JANINO" system property.

For JCI+Janino to compile your rule base, it is enough to have dynamically generated classes available into your context class loader. So, for instance, if your dynamically generated classes were loaded into the same ClassLoader that loaded your Main application class, only thing you need to do is to call, before creating your PackageBuilder:

Thread.currentThread().setContextClassLoader( Main.class.getClassLoader() );


This will ensure that your PackageBuilder will use the provided class loader to find the classes for compilation. That will obviously succeed as the given class loader is the one that loaded your dynamic classes.

1.2. JDT

JDT is the default compiler for JBoss Rules. If you don't set the "drools.compiler" property, nor change it using the PackageBuilderConfiguration.setCompiler() method, it will be used to compile your rules.

Although, JCI+JDT have an additional requirement: to compile your rule base, the context class loader must be able to provide the actual classes’ bytecode, not only the loaded classes. In other words, you must provide a custom class loader that can provide an input stream for the byte code of each class used in your rule base.

In the above rule example, your custom class loader must return the input stream to the byte code of Person and Cheese classes, does not matter if the classes were dynamically generated or not.

For dynamically generated classes, it is enough for the custom class loader to implement the method:

public InputStream getResourceAsStream(final String name);


I have written a simple example that has a ClassLoader that uses a simple HashMap to store dynamically generated classes bytecodes and return them when the appropriate getResourceAsStream method is called.

So, what you need to do is similar to what you do in Janino:

Thread.currentThread().setContextClassLoader( myCustomClassLoader );


But, your custom class loader must comply with the above requirement.

2. Rules Execution

Rules execution may happen immediately after rules compilation or not. For example, you may compile a rule base and serialize it at build time. At runtime you simply deserialize the rule base and execute it.

The only thing you need to do at execution time is to make sure the same ClassLoader hierarchy used to load your rule base is used to load your fact classes. Again, this is not related to dynamically generated classes, but the problem of multiple ClassLoader shows up more frequently when using dynamically generated classes, because this one of the situations when people usually use multiple ClassLoaders inside the same application.

Just to understand the problem, remember that in java, a class C loaded by loader L1 is different from the same class C loaded by loader L2. So, if you load above rule base with class loader L1 and assert into working memory a Cheese class instance loaded by class loader L2, your rule will never match and obviously never fire.

So make sure your rule base does not load your classes in a different class loader than your application is using to load it.

Example

I created a very simple example of JBoss Rules using dynamically generated classes as facts and committed it here. It is not intended to be a general purpose solution, but rather a didactic example of one possible solution.

I am using ASM as the bytecode generation framework and kept the API functional but simple in order to not overload the example.

The example uses a Customer bean that is a regular POJO class and two dynamically generated classes: Order and LineItem.

Feel free to drop questions you may have to the JBoss Rules users list.

[]s
Edson

Friday, December 08, 2006

Rush Hour and Content Based Routing (Michael Neale)

Recently I (and Mark) attended JBoss World in Berlin. We ran a few sessions on rules, and had 2 excellent end user presentations, all was well received. Its good to see the cool stuff people are doing with rules, so I thought I would share a summary.

Content Based Routing - Michael Frandsen (Syngenio)
Content Based Routing (CBR) is used in messaging systems when you need to, well, route messages, based on, er, content ! Pretty obvious really ! Normally this is part (in some form) of messaging middleware or things like ESBs (enterprise service bus). In fact, its part of JBoss ESB (something I confess I am not overly familiar with, what with working on our own product, we don't get to look around at our stable mates that often, but I do know they use rules).

CBR is also known as "smart routing" and can be used for clever things like routing messages based on transaction value (ie higher value purchases get special treatment when load balancing) or based on things like who the customer is, the possibilities are endless.

Michael Frandsen (JSR-94 lead/contributor) has been working on CBR as part of his day job. He used rules (starting with Drools 2.5, moving up to 3.0.4) and XPath to provide declarative routing rules based on message content (which can be arbitrarily complex as needed, and perhaps involve large numbers of rules). Generally XPath or similar is used, as it provides a declarative way to make assertions over the *contents* of a message (normally the actions in routing is very simple, just telling it where to send the message !).

Michael's architecture on how the rule engine can reason over message contents for CBR.


The issue with XPath is that it is not known for its raw performance, but for IO and stateless things like message routing, you would think this is not really an issue. Couple this with the fact that a lot of the times the routing rules are minimal, I would have though XPath would shine compared to a rule engine for message routing.

Oh how wrong I was. Michael showed that even for the simplest cases, the smallest number of rules, that JBoss Rules blew away XPath implementations - this shocked me as normally rules shine with stateful scenarios (but all his message routing rules are stateless), but would not have as much advantage for stateless.

Moreover, when the complexity and number of rules scaled up (Michael pushed it to 1000 rules, which would be a LOT of rules for routing, but in some enterprises, it is possible) XPath was much slower then the rule based approach.

From this table you can see that JBoss Rules is at least 2 (sometimes 3) orders of magnitude faster then XPath. The nice scaling of throughput as the rule count increases also shows RETE really paying off. Note that this is for STATELESS CBR, and in no case is the rules approach slower, always faster. You can also see the jump from Drools 2.5 to Drools 3 (JBoss Rules) which re-inforces the power of full-RETE.


Using DRL+DSL for message routing also made for very attractive routing rules (none of this is using XPath):

You can see Michael's presentation here.

Traffic control (Leo van den Berg)

UPDATE: The presentation for this in PDF format can be downloaded from here.
Leo van den Berg, working with the University of Valencia and the Dutch ministry of transportation, has been working on a rule based traffic management system. We all know and love gridlock in our major cities, and what they are doing is building open source tools and applications for "traffic engineers" to use.

Traffic control systems do things like display messages on electronic boards, close and open lanes, traffic lights, accident reports, emergency response etc.

The architecture used uses JMS heavily to collect "event" data as asynchronous messages, and feed it (after some filtering) to the rule engine. The rule engine collects/reasons over this data, and they makes conclusions (included in Leo's demo was triggering an SMS warning to tell and engineer to open an optional lane).

Leo even had a cool live demo - using their thick client front end - which had awesome stuff like live video feeds from the relevant traffic cameras. Seeing a use case like this was great to see. I imagined it like a Giant Mind watching over us (well, those in Amsterdam etc at least). But you can relax, at the end of the day, its the traffic engineers (humans) who actually do the real button pushing/decisions based on the informations and suggestions given to them. So its not SkyNet just yet ;)

Hopefully I can show you some more of this application in a future post. The really nice thing is that what they are working on will be open source as well.


Ich bin ein Berliner !

Friday, December 01, 2006

New visual rule builder (Michael Neale)

I have been beaving away on a new UI/rule modeller specifically for the web (well, at least the web initially, hopefully we will also do it stand alone in the plug in soon).

This came about for 2 reasons:
1) DSLs have proven to be quite popular, and we want to make them available on the web (essentually a very handy templating tool for capturing rule data), and
2) I thought it would be nice to have a helpful and user friendly UI to "coach" people in authoring optimal rules (developers can also look at the drl output, see what makes it tick !).
(and 3: I had some spare brain cycles during JBoss world to work on it! and I thought the above 2 aims could be combined).

Since a picture is worth a thousand words, here is a screenshot:



This should be available in the up coming rule repository user interface. Visually its still quite rough, but its getting there, and the model behind it is solid. I would appreciate any feedback on how to make this a more "intuitive" interface to use (and don't confuse it with decision tables or scorecards, thats another beastie, this is just for a single rule at a time management).

I am integrating this with the (previously seen) dsl-aware business rule editor, as it is a nice fit (some people will use DSLs exclusively to hide details, others may use the modeller exclusively, perhaps a mix - yet more may prever vanilla drl, or a mixture in a package).

One of the nice things about it is that it requires little/no configuration (whereas there is some skill to configuring a dsl - this editor is driven off the model: facts/fields define what operators are relevant etc) - of course a dsl based rule reads naturally, but it is also easy to understand what the rule is doing visually if the model matches the domain. (A future fun little task will be to generate read only statements of the rules - a la the rule builder for email clients for filtering out that pesky spam).

So hows it work: A thats a trade secret ! Oh wait, no its not, its already in the SVN repository probably being crawled all over by google as we speak ! (oh my embarrasing code !). It works as it knows about the facts (model) available to the rules, what operators are applicable, bound variables, and has a limited set of actions it can take (mostly asserting fact, retracting, modifying fields, globals etc - I may add more as needed, but DSLs can template more things as needed).

I am planning to make the operator names/conditional element names configurable (they will have prettier defaults then this, I just ran out of time to do that, the idea is that anyone understanding basic logic should be able to use this, and if they know first order logic, all the better !).

It also has some basic validation (for instance you can't remove a fact that is needed in an action) - lots more can be done with validation to ensure correct rules at the time of entry (rule analysis module is another, seperate topic and a hobby of mine !)

Enjoy !