Почему kieServices в файле классе Main имеет значение null?

Рейтинг: 3Ответов: 1Опубликовано: 12.03.2023

Почему kieServices в файле классе Main имеет значение null? Используется maven и drools в IDE Eclipse, суть приложения: Приложение для управления бизнес-правилами на основе Drools.

Все необходимые библиотеки Drools я поставил. Ниже pom.xml .

Описание ошибки:

Exception in thread "main" java.lang.NullPointerException: 
Cannot invoke "org.kie.api.KieServices.getKieClasspathContainer()" because "kieServices" is null
    at com.javainuse.main.Main.main(Main.java:13)

проект находится здесь.

Код проекта:

main.java:

package com.javainuse.main;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.javainuse.model.Product;

public class Main {
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();
        Product product = new Product("soda", 5, true, 2);
        kieSession.insert(product);
        kieSession.fireAllRules();
        kieSession.dispose();
    }
}

Product.java:

package com.javainuse.model;

public class Product {
    public String name;
    public int quantity;
    public boolean onPromotion;
    public int emptyBottles;

    public Product(String name, int quantity, boolean onPromotion, int emptyBottles) {
        this.name = name;
        this.quantity = quantity;
        this.onPromotion = onPromotion;
        this.emptyBottles = emptyBottles;
    }

}

Rules.drl:

package com.rule

import com.javainuse.model.Product


rule "Check promotion"
    when
        $p : Product(name == "soda", onPromotion == true)
    then
        System.out.println("The product is on promotion!");
    end


rule "Check number of bottles"
    when
        $p : Product(name == "soda", quantity >= 2)
    then
        System.out.println("You can exchange two empty bottles for one new bottle!");
    end


rule "Check number of empty bottles"
    when
        $p : Product(name == "soda", emptyBottles >= 2)
    then
        System.out.println("You can exchange two empty bottles for one new bottle!");
    end

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javainuse</groupId>
  <artifactId>lab1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
        <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-core</artifactId>
          <version>7.59.0.Final</version>
        </dependency>
    </dependencies>
</project>

Ответы

▲ 1Принят

У вас используется новая версия JDK, которая сразу указывает в сообщении об ошибке, что экземпляр класса KieServices kieServices является null в методе main на строке №13, и поэтому вызов метода getKieClasspathContainer() для данной переменной невозможен.

Экземпляр сервиса у вас создаётся в строке:

public class Main {
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get(); // !!!!!
// ...
}

то есть, проблема в том, что у вас вызов KieServices.Factory.get() возвращает null.

Запрос в гугл: kieservices.factory.get() returns null возвращает несколько ссылок на аналогичную проблему на основном StackOverflow: введите сюда описание изображения

Основные решения для этой проблемы указаны по ссылке Drools 7.4.1 kieservices.factory.get() returns null:

  1. Необходимо добавить зависимость в pom.xml на компилятор Drools:
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>7.4.1</version>
    </dependency>
  1. Также может понадобиться модифицировать файл конфигурации drools-core kie.conf и добавить в него строки:
org.kie.api.KieServices = org.drools.compiler.kie.builder.impl.KieServicesImpl
org.kie.internal.builder.KnowledgeBuilderFactoryService = org.drools.compiler.builder.impl.KnowledgeBuilderFactoryServiceImpl