javamavendroolsdrools-guvnorkie

Loading Drools/KIE Workbench artifacts directly from the repository


We try to switch to Drools 6 with the all new KIE workbench (formerly known as Guvnor) and the new maven-based artifacts.

Now I'd like to use the the system described in this blog post in the second image ("Deployment"): Loading the rules via HTTP from the workbench repository (the dotted arrow, going from HTTP on the left directly into the application).

The problem is, that I have no idea how to load the artifact into my KieServices/KieModule object. I basically do not want to use maven, I also cannot provide the path to maven's settings.xml globally as a Java parameter, so this option is out.

I think that a similar issue is this one. As mentioned there, I also tried to load an URL resource but the problem seems to be that the system cannot determine, what kind of ResourceType the given URL (http://localhost:8080/kie-drools/maven2/.../-1.0.0.jar) is. And yes, I can access the .jar from the repository directly from the browser, without authentication.

Any ideas or tutorials how to do this?

My testing code:

public static void main(String[] args) {
    KieServices ks = KieServices.Factory.get();
    KieRepository repo = ks.getRepository();

    String url = "http://localhost:8080/kie-drools/maven2/de/test/test/1.0.0/test-1.0.0.jar";

    Resource urlResource = ks.getResources().newUrlResource(url);
    KieModule kModule = repo.addKieModule(urlResource); // this already fails
}

The error:

Exception in thread "main" java.lang.RuntimeException: Unable to fetch module from resource :[UrlResource path='http://localhost:8080/kie-drools/maven2/de/itm/Herma400/1.0.1/Herma400-1.0.1.jar']
    at org.drools.compiler.kie.builder.impl.KieRepositoryImpl.getKieModule(KieRepositoryImpl.java:205)
    at org.drools.compiler.kie.builder.impl.KieRepositoryImpl.addKieModule(KieRepositoryImpl.java:161)
    at kieTest.MainKieTest.main(MainKieTest.java:24)
Caused by: java.lang.NullPointerException
    at org.drools.compiler.kie.builder.impl.ClasspathKieProject.getPomProperties(ClasspathKieProject.java:197)
    at org.drools.compiler.kie.builder.impl.ClasspathKieProject.fetchKModule(ClasspathKieProject.java:148)
    at org.drools.compiler.kie.builder.impl.ClasspathKieProject.fetchKModule(ClasspathKieProject.java:109)
    at org.drools.compiler.kie.builder.impl.KieRepositoryImpl.getKieModule(KieRepositoryImpl.java:190)
    ... 2 more

Thanks in advance!


Solution

  • I finally managed to get this solved. Below is a working example which loads the Drools artifact from the KIE-repository via HTTP and executes the rules:

    package kieTest;
    
    import java.util.Scanner;
    
    import org.drools.compiler.kproject.ReleaseIdImpl;
    import org.kie.api.KieServices;
    import org.kie.api.builder.KieScanner;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.StatelessKieSession;
    
    public class MainKieTest {
    
        public static void main(String[] args) {
    
            // works even without -SNAPSHOT versions
            String url = "http://localhost:8080/kie-drools/maven2/de/test/Test/1.2.3/Test-1.2.3.jar";
    
            // make sure you use "LATEST" here!
            ReleaseIdImpl releaseId = new ReleaseIdImpl("de.test", "Test", "LATEST");
    
            KieServices ks = KieServices.Factory.get();
    
            ks.getResources().newUrlResource(url);
    
            KieContainer kieContainer = ks.newKieContainer(releaseId);
    
            // check every 5 seconds if there is a new version at the URL
            KieScanner kieScanner = ks.newKieScanner(kieContainer);
            kieScanner.start(5000L);
            // alternatively:
            // kieScanner.scanNow();
    
            Scanner scanner = new Scanner(System.in);
            while (true) {
                runRule(kieContainer);
                System.out.println("Press enter in order to run the test again....");
                scanner.nextLine();
            }
        }
    
        private static void runRule(KieContainer kieKontainer) {
            StatelessKieSession kSession = kieKontainer.newStatelessKieSession("testSession");
            kSession.setGlobal("out", System.out);
            kSession.execute("testRuleAgain");
        }
    }
    

    When searching for the solution, I found the following link helpful:

    I hope someone finds this useful when getting SO as first search result ;-)