0
votes
java.lang.RuntimeException: Unexpected global [log]
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1163)
  1. DRLs are retrieved from a database as list of Strings.
  2. We dont use kmodule.xml Following the comments : The DRL (minimized the setup to try and locate the issue) is loaded without a hitch but somehow the globals defined in it, are not .

KieSession creation code

 KieServices ks = KieServices.Factory.get();
        KieRepository kr = ks.getRepository();
        KieFileSystem kFileSystem = ks.newKieFileSystem();

        int i=0;
        for (String ruleId : drls.keySet()){
            Resource resource = ks.getResources().newByteArrayResource(drls.get(ruleId).getBytes());
            resource.setTargetPath("./out/"+ ruleId +".drl");
            resource.setResourceType(ResourceType.DRL);
            kFileSystem.write(resource);
        }
        KieBuilder kieBuilder = ks.newKieBuilder( kFileSystem );
        kieBuilder.buildAll();
    KieBuilder kieBuilder = ks.newKieBuilder( kFileSystem );
    kieBuilder.buildAll();
    if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
        log.error(PolicyUtils.createMsg("DRL Errors:\n" + kieBuilder.getResults().toString()), context, null, null);
        throw new RuntimeException("DRL Errors:\n" +         kieBuilder.getResults().toString());
    }
    kContainer = ks.newKieContainer(kr.getDefaultReleaseId());
    kContainer.newKieSession();
2
Are you validating that the KieBase you are creating doesn't contain any error? Just for completeness sake, could you post the following: the structure of where your DRL files are, your kmodule.xml and the code you are using to build your KieBase. - Esteban Aliverti
@EstebanAliverti So much time, mine and others', has been wasted due to sessions being created from an empty rulebase (whatever the reason) and people running in circles, chasing an error elsewhere. Why is there no exception? - laune

2 Answers

2
votes

After reading your chat with @laune in the other answer, I guess that the problem is now identified: Your KieBase doesn't contain the artifacts (rules, globals, etc.) you think it does.

No idea what could be wrong with your code, but I think a simple workaround could save you from all that boilerplate (and error-prone) code you have there.

The idea here is to use the KieHelper class instead of using KieRepository, KieFileSystem and KieBuilder. Actually, the KieHelper class was created to avoid this complicated steps (in comparison with Drools 5.x) involved in the creation of a KieBase.

Using the KieHelper class, you can refactor your code to look similar to this:

KieHelper kieHelper = new KieHelper();
for (String ruleId : drls.keySet()) {
    kieHelper.addContent(drls.get(ruleId), ResourceType.DRL);
}
Results results = kieHelper.verify();
for (Message message : results.getMessages()) {
    log.error(">> Message ({}): {}", message.getLevel(), message.getText());
}

if (results.hasMessages(Message.Level.ERROR)) {
    throw new IllegalStateException("There are errors in the KB.");
}

KieSession ksession = kieHelper.build().newKieSession();

Hope it helps,

1
votes

In your Java code you have some call like

kieSession.setGlobal( "log", ... );

which should have a counterpart in your .drl file such as

global ... log;

but it has not. (The dots mark the place for an object reference and the corresponding type, respectively.)

Seeing your code...

kFileSystem.write(resource);

I strongly recommend that you use the form with this relative path:

kFileSystem.write( "src/main/resources/" + ruleId + ".drl,
                   resource );

or modify the resource target path:

resource.setTargetPath("src/main/resources/hello.drl");

(Your code does not work:

resource.setTargetPath("./out/hello.drl");

Later, during compilation, this causes a warning "No files found for KieBase defaultKieBase". The Drools manual contains this sentence "These artifacts have to be added in the same position of a corresponding usual Maven project." but doesn't simply explain what this means, which would be much more helpful.)

Not having the "global" in your DRL code is, of course, equivalent to a failure to compile a knowledge base, i.e., your session is running on an empty knowledge base.