Search code examples
javadroolskie

How can I get all of the globals required by a KieSession?


I'm using Drools and I am inserting quite a few globals into a KieSession.

kieSession.setGlobal("foo", foo);
kieSession.setGlobal("bar", bar);
kieSession.setGlobal("baz", baz);
//...

Every object I'm using as a global exists as a Spring bean and so it occurs to me that if I had a list of what globals were expected, I could simply "autowire" the session.

Map<String, Class<?>> globals = getGlobals(kieSession);
globals.forEach((name, clazz) -> 
    kieSession.setGlobal(name, beanFactory.getBean(clazz))
);

There is a method called getGlobals but it only appears to return globals that have already been inserted.

From attaching the debugger, I can see that a map of these values exists inside the KieBase, and I wrote a method to get it via reflection:

@SuppressWarnings("unchecked")
@SneakyThrows //Lombok turns the checked exceptions into unchecked
private Map<String, Class<?>> getGlobals(final KieSession session)
{
    final KieBase kieBase = session.getKieBase();
    final Field globals = kieBase.getClass().getDeclaredField("globals");
    globals.setAccessible(true);
    return (Map<String, Class<?>>) globals.get(kieBase);
}

This works but I would rather not resort to reflection unless it's absolutely necessary.

Is there a better way to accomplish this? If not, is there a good reason why this information is encapsulated so that I couldn't ordinarily access it?


Solution

  • You can get the globals from a KiePackage. Just iterate KiePackages that you get from a KieBase.

    final Collection<KiePackage> kiePackages = kieSession.getKieBase().getKiePackages();
    for (KiePackage kiePackage : kiePackages)
    {
        final Collection<Global> globalVariables = kiePackage.getGlobalVariables();
        //...
    }