14

I try to integrate Drools 7.4.1 into a webapp in tomcat.

When I call in the code the following statement to get a KieService I get null.

KieServices ks = KieServices.Factory.get();

When the same method is being called from a test method it is ok.

Can anyone help on this?

Eggcellentos
  • 1,570
  • 1
  • 18
  • 25

8 Answers8

12

You have to add drools-compiler in your dependencies.

    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>7.4.1</version>
    </dependency>
freedev
  • 25,946
  • 8
  • 108
  • 125
10

Thanks for the tip nicole.torres.

For this problem we can use the appendingtransformer avalaible in the maven-shade-plugin resource transformers:

https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html#AppendingTransformer

Using this we can append all META-INF/kie.conf files. Anyone facing a null pointer when creating a KieBase or KieContainer in an ubber jar, visit this thread. I spent three days to find the solution and tried to create an ubber jar for almost every damn drools example available online :(

Carlos Costa
  • 195
  • 1
  • 11
7

We had the same issue when trying to use Drools in our webserver with embedded Grizzly http server.

We also needed to add the drools-compiler dependency, but that alone does not fix it.

Because there are multiple kie.conf files on the class path from the different dependencies, the uber-jar ends up having just one, and then definitions for classes to load are missing.

Besides these entries from the drools-core kie.conf:

org.kie.api.io.KieResources = org.drools.core.io.impl.ResourceFactoryServiceImpl
org.kie.api.marshalling.KieMarshallers = org.drools.core.marshalling.impl.MarshallerProviderImpl
org.kie.api.concurrent.KieExecutors = org.drools.core.concurrent.ExecutorProviderImpl

we added these lines from drools-compiler to our uber-jar kie.conf:

org.kie.api.KieServices = org.drools.compiler.kie.builder.impl.KieServicesImpl
org.kie.internal.builder.KnowledgeBuilderFactoryService = org.drools.compiler.builder.impl.KnowledgeBuilderFactoryServiceImpl

Otherwise the KieServices were not loaded and KieServices.Factory.get() returned null.

We are modifying the built jar afterwards using

jar uf myjar.jar META-INF/kie.conf

to modify the contained kie.conf file. We couldn't find a clean integrated solution with Maven. Any suggestions welcome...

nicole.torres
  • 307
  • 2
  • 6
3

As suggested by @Carlos Costa, below changes in pom.xml solved the issue.

Summarizing all suggestions, below is the detailed solution. In pom.xml, add the following.

<dependencies>
  <dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>${runtime.version}</version>
  </dependency>
</dependencies>

And

<build>
  <plugins>
    <plugin>
      <executions>
        <execution>
          <configuration>
            <transformers>
              <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/kie.conf</resource>
              </transformer>
            </transformers>
          </configuration>
       </execution>
     </executions>
    </plugin>
  </plugins>
</build>
Ayaz Pasha
  • 1,045
  • 6
  • 13
  • 28
  • 1
    We did this and it worked. The kie.conf file at first had 3 lines of properties. After doing this it had about 25 (they all get combined). O, and the Transformer needs to be added to the Shade plugin in the Execution section. – markthegrea Aug 21 '20 at 19:47
2

If you are building using gradle and shadow jar, you can append the kie.conf files together by modifying the shadowJar task

shadowJar {
    mergeServiceFiles()
    transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer) {
      resource = "META-INF/kie.conf"
    }
}
hmatt1
  • 4,939
  • 3
  • 30
  • 51
1

You have to add this two dependencies and {version} of both dependencies must be the same

<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-core</artifactId>
  <version>{version}</version>
</dependency>

<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-compiler</artifactId>
  <version>{version}</version>
</dependency>
S.Daineko
  • 1,790
  • 1
  • 20
  • 29
1

Use the latest drools jar package version.

  <properties>
        <drools-version>7.16.0.Final</drools-version>
  </properties>
   <dependencies>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>${drools-version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>${drools-version}</version>
        </dependency>
</dependencies>

Merlin
  • 61
  • 1
  • 4
1

This could be happening because you're using an uber-jar, as suggested by nicole.torres.

Another solution is to manually fetch the contents of all META-INF/kie.conf from your dependencies (i.e. drools-core, drools-compiler, etc) and add them into your project src/main/resources/META-INF/kie.conf file.

The advantage over the other solution is that you don't need to manually modify the JAR after packaging it.

If you're not using an uber-jar then the problem could be something else, since all the dependencies should be available at runtime.