How to make drools drl files available for updated jar at runtime

I recently worked on a drools project, where I ran into certain problems and I need help. In my project, I access the jar at runtime using the URLClassLoader. Here is the code:

Object object=null;
 Class myclass=null;
 URL jarPath=null;
 try{
    jarPath=new File("lib/Billing.jar").toURI().toURL();
    URLClassLoader loader = new URLClassLoader(new URL[] { jarPath },ClassLoader.getSystemClassLoader());
    ruleclass = loader.loadClass("dynamicclasses.Billing");
    object = ruleclass.newInstance();                       
}
catch (Exception e) {e.printStackTrace}

After receiving the class instance, I set the values ​​and pass the object to the drooles class

new DroolsClass().fireRules(object);

The drools class contains the following code:

public class DroolsClass {
public void fireRules(Object object){   
        try {
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            ksession.insert(object);
            ksession.fireAllRules();                    
            logger.close();

        } catch (Throwable t) {
            t.printStackTrace();    
        }

}
private static KnowledgeBase readKnowledgeBase() throws Exception {

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newFileResource("./rulefiles/testing.drl"), ResourceType.DRL);
            KnowledgeBuilderErrors errors = kbuilder.getErrors();
        // ------ some code
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
}

Next, I have a drl testing.drl file that is present in the file directive and which accesses the same dynamicclasses.Billing class that is present in Billing.jar

Here is the contents of the drl file:

import dynamicclasses.Billing;

rule "rule 3"

salience 10 
dialect "mvel" 
no-loop true
when
     m : Billing(bplan=="plan1")
then
    System.out.println("You have opted for plan1");   
end

The problem I am facing is when the jar ie Billing.jar is updated while the drl file is running ie testing.drl cannot access the updated jar.

, .

1) jar , . 2) drl , , jar i.e. dynamicclasses.Billing

jar java URLClassLoader. drools, .

Unable to resolve ObjectType 'Billing' : [Rule name='rule 3']

Error importing : 'dynamicclasses.Billing'
java.lang.IllegalArgumentException: Could not parse knowledge.

, , jar , , , drl, .

:

URLClassLoader loader = new URLClassLoader(new URL[] { jarPath },this.getClass().getClassLoader());

. , , .

, , .

, , drl . , ?

.

+3
3

:) , . KnowledgeBuilderConfiguration, KnowledgeBaseConfiguration, .

private static KnowledgeBase readKnowledgeBase(ClassLoader loader) throws Exception {

        KnowledgeBuilderConfiguration kBuilderConfiguration = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, loader);
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(kBuilderConfiguration);

        KnowledgeBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(null, loader);

        kbuilder.add(ResourceFactory.newFileResource("./rulefiles/testing.drl"), ResourceType.DRL);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();

        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig);
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    } 
+2

KnowledgeBuilder KnowledgeBuilderConfiguration.

ClassLoader loader = new URLClassLoader(
    new URL[] { jarPath },
    ClassLoader.getSystemClassLoader());
KnowledgeBuilderConfiguration kBuilderConfiguration 
    = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, loader);
KnowledgeBuilder kbuilder 
    = KnowledgeBuilderFactory.newKnowledgeBuilder(kBuilderConfiguration);
+1

For Drool 6.5.0, the class loader can be added:

kieServices = KieServices.Factory.get();

KieFileSystem kieFileSystem = kieServices.newKieFileSystem();        
kieFileSystem.write("./rulefiles/testing.drl", drl);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem, loader);
kieBuilder.buildAll();

KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId(), 
            pluginCtxObject.getClass().getClassLoader());
StatelessKieSession statelessKieSession = kieContainer.getKieBase().newStatelessKieSession();
statelessKieSession.execute(object);
0
source

All Articles