I'm looking into providing a 'hot-swap' capability for switching between different versions of sets of drools rules. The target deployment is in WebSphere, and the rules will all be run in stateless session beans. Ideally I want to pre-compile and package the rules into some discrete file and get the Application Server to determine that new rules are available, and load them (skipping the compilation step).
The Drools documentation indicates this should be possible - but is splendidly vague on the mechanics. The details on the Java EE side are not an issue but the pre-compilation is providing an headache.
Following some posts I've pulled together some logic which I thought would do the trick - the following compiles a rules file and serializes it out to disk:
private void process(String outputFile, String inputFile) throws Exception {
String drl = fileToString(inputFile);
KieServices ks = KieServices.Factory.get();
KieFileSystem kfs = ks.newKieFileSystem().write( "src/main/resources/r1.drl", drl );
ks.newKieBuilder( kfs ).buildAll();
ReleaseId releaseId = ks.getRepository().getDefaultReleaseId();
InternalKieModule kieModule = (InternalKieModule) ks.getRepository().getKieModule( releaseId );
byte[] jar = kieModule.getBytes();
serialize(jar, outputFile);
System.out.println("Class of InternalKieModule is " + kieModule.getClass());
}
The following reads it back ready to create a KieSession:
private KieContainer getKbase(KieServices ks) throws Exception {
byte[] jar = deserialize(RULES_SER);
Resource jarRes = ks.getResources().newByteArrayResource(jar);
KieModule km = ks.getRepository().addKieModule(jarRes);
releaseId = km.getReleaseId();
KieContainer kc = ks.newKieContainer(km.getReleaseId());
return kc;
}
Works fine BUT ... I was horrified to discover I seem to need everything but the kitchen sink to actually run it - just under 50 separate jar files - taking up 16 MB and including the Ant jar, 10 Maven jars, and the drools compiler jar even though I'm not supposed to be compiling anything, and I'm certainly not trying to use Maven or Ant! Of the 67 Jar files in the distribution nearly all seem directly linked to Maven, and very few (I'd judge from the approach below about 10 to 15) actually have anything to do with a rules runtime.
Going back to an example I built with Drools 5, several years back, I came up with the following code to reload a drl file I'd compiled separately using the Knowledge Base APIs:
private KnowledgeBase readSavedKnowledgeBase() throws Exception {
byte[] serializedKb = (byte[]) deserialize(RULES_SER);
ByteArrayInputStream bais = new ByteArrayInputStream(serializedKb);
DroolsObjectInputStream ois = new DroolsObjectInputStream(bais);
KnowledgeBase kbase = (KnowledgeBase) ois.readObject();
ois.close();
return kbase;
}
This works fine with 6.1. I only need 9 jars, (and I don't need the compiler jar) - and my run-time is a fairly reasonable 5MB. The down side is that Eclipse is unhappy since the KnowledgeBase class is now deprecated.
Could someone point the way to allowing me to get the same result using non-deprecated classes but without all the baggage of Maven and so on which I don't want or need to actually run some rules?