Получение ошибки при установке drools 6 с помощью spring 4. Метод processData (LicenseCredential) не определен для типа Rule_Renewal_alert_for_60]

Я новичок в Drools. Я настроил новый проект с spring-4.1 и drool-6.1.0.Final. Но когда я пытаюсь запустить проект, я получаю следующие ошибки

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autoalert-ksession-stateless': Cannot resolve reference to bean 'autoalert-kbase' while setting bean property 'kBase'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autoalert-kbase': Invocation of init method failed; nested exception is java.lang.RuntimeException: Error while creating KieBase[Message [id=1, level=ERROR, path=drools/rules/Rule.drl, line=27, column=0
text=[ function processDataprocessData (line:27): learnerCsvFileWriter cannot be resolved
]], Message [id=2, level=ERROR, path=drools/rules/Rule.drl, line=33, column=0
  text=Rule Compilation error The import defaultpkg.ProcessData cannot be resolved
The method processData(LicenseCredential) is undefined for the type Rule_Renewal_alert_for_60_days2039807096], Message [id=3, level=ERROR, path=drools/rules/Rule.drl, line=-1, column=0
text=Error importing : 'defaultpkg.ProcessData.processData']]

Вот мои файлы конфигурации spring и drools

слюни-context.xml

<kie:kmodule id="autoalert-module">
    <kie:kbase name="autoalert-kbase" packages="drools.rules">
        <kie:ksession name="autoalert-ksession-stateless" type="stateless"  />
    </kie:kbase>
</kie:kmodule>

<bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

applicationContext.xml

<context:annotation-config />              
<context:property-placeholder location="classpath:autoalert.properties" ignore-unresolvable="true" /> 

<import resource="classpath:database/datasource-tx.xml" />
<import resource="classpath:drools/drools-context.xml" />

<bean id="csvFileWriter" class="com.softech.vu360.autoalert.CsvFileWriter" />

<bean id="businessRuleProcessor" class="com.softech.vu360.autoalert.rule.BusinessRuleProcessor">
    <property name="statelessKieSession" ref="autoalert-ksession-stateless" />
    <property name="csvFileWriter" ref="csvFileWriter" />
</bean>

Вот мой файл правил.

import com.softech.vu360.autoalert.util.Utility;
import static com.softech.vu360.autoalert.util.Utility.getCurrentDate;
import static com.softech.vu360.autoalert.util.Utility.getDate;
import static com.softech.vu360.autoalert.util.Utility.getMonthNameFromInt;
import com.softech.vu360.autoalert.model.LicenseCredential;
import com.softech.vu360.autoalert.model.Learner;
import com.softech.vu360.autoalert.CsvFileWriter;
import com.softech.vu360.autoalert.mail.EmailRegistrationService;
import java.util.Date;

global com.softech.vu360.autoalert.CsvFileWriter learnerCsvFileWriter;

function void processData(LicenseCredential licenseCredential){

    Learner learner = new Learner();
    learner.setLearnerName(licenseCredential.getLearnerName());  
    learner.setLearnerEmailAddress(licenseCredential.getLearnerEmailAddress());
    learner.setUserGUID(licenseCredential.getUserGUID());
    ...
    learnerCsvFileWriter.add(learner);

}

rule "Renewal alert for 60 days"
    when
        licenseCredential : LicenseCredential()
        (
            eval(licenseCredential.getRenewalDeadlineDay() == "0" && licenseCredential.getRenewalDeadlineMonth() == "0") && 
            eval(getCurrentDate().after(getDate(2, licenseCredential.getCourseCompletionDate().getDate(), licenseCredential.getCourseCompletionDate().getMonth()+1))) && 
            eval(getCurrentDate().before(getDate(1, licenseCredential.getCourseCompletionDate().getDate(), licenseCredential.getCourseCompletionDate().getMonth()+1))) 
         ) ||
        (
            eval(getCurrentDate().after(getDate(2, Integer.valueOf(licenseCredential.getRenewalDeadlineDay()), Integer.valueOf(licenseCredential.getRenewalDeadlineMonth()) ))) &&
            eval(getCurrentDate().before(getDate(1, Integer.valueOf(licenseCredential.getRenewalDeadlineDay()), Integer.valueOf(licenseCredential.getRenewalDeadlineMonth() )))) 
        )
    then
        System.out.println("Rule For 60 Days Called");      
        processData(licenseCredential);
end

Вот мой POM-файл:

<properties>
    <java-version>1.8</java-version>
    <junit.version>4.12</junit.version> 

    <!-- Spring -->
    <org.springframework.version>4.1.4.RELEASE</org.springframework.version>

    <!-- Drools -->
    <drools.version>6.1.0.Final</drools.version>
    <drools-maven-plugin.version>6.0.0.CR5</drools-maven-plugin.version>

    <maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
   ...

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<dependencies>

    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    ....
    <!-- Drools -->
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>${drools.version}</version>
    </dependency>

    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-ci</artifactId>
        <version>${drools.version}</version>
    </dependency>

    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-spring</artifactId>
        <version>${drools.version}</version>
    </dependency>

    <dependency>
        <groupId>org.jbpm</groupId>
        <artifactId>jbpm-bpmn2</artifactId>
        <version>${drools.version}</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${org.slf4j-version}</version>
    </dependency>
</dependencies>

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>

        <!-- Maven compiler plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>${java-version}</source>
                <target>${java-version}</target>
            </configuration>
        </plugin>
        ....
        <plugin>
            <groupId>org.drools</groupId>
            <artifactId>drools-maven-plugin</artifactId>
            <version>${drools-maven-plugin.version}</version>
            <extensions>true</extensions>
        </plugin>
    </plugins>
</build>

Вот мой основной файл

public static void main(String[] args){ 

    final ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");

    LicenseCredentialDAO dao = (LicenseCredentialDAOImpl)context.getBean("licenseCredentialDAO");
    List<LicenseCredential> objectList = dao.select();

    BusinessRuleProcessor ruleProcessor = (BusinessRuleProcessor)context.getBean("businessRuleProcessor");
    ruleProcessor.configureAndApplyRulesOnObject(objectList);

    CsvFileWriter learnerCsvFileWriter = context.getBean("csvFileWriter", CsvFileWriter.class);
    learnerCsvFileWriter.writeCsvFile("abc.csv");

}

Вот мой класс BusinessRuleProcessor

public class BusinessRuleProcessor {
    private StatelessKieSession statelessKieSession;
    private CsvFileWriter csvFileWriter;

    // getters and setters

    public void configureAndApplyRulesOnObject(List<LicenseCredential> objectList){

        statelessKieSession.setGlobal("learnerCsvFileWriter", csvFileWriter);
        statelessKieSession.execute(objectList);

    }
}

Почему я получаю сообщение об ошибке

function processDataprocessData (line:27): learnerCsvFileWriter cannot be resolved

Rule Compilation error The import defaultpkg.ProcessData cannot be resolved

The method processData(LicenseCredential) is undefined for the type Rule_Renewal_alert_for_60_days2039807096]

Пожалуйста помоги.

Спасибо


person Basit    schedule 23.02.2015    source источник
comment
У меня есть ощущение, что это может быть связано с проблемами, которые у вас есть с определениями пакетов. Похоже, вы не удосужились задать имя пакета для своего правила (отсюда defaultpkg), но поместили его в package; drools/rules/.   -  person Steve    schedule 23.02.2015
comment
Вы хотите сказать, что мне нужно определить объявление пакета в моем файле правил. Нравится package drools.rules; в моем файле drl?   -  person Basit    schedule 23.02.2015
comment
Это отправная точка. Drools ищет правила, определенные в пакетах под src/main/resources, следуя структуре пакетов в стиле Java. Как и в случае с классом Java, если правило находится в каталоге drools/rules, оно должно объявить свой пакет как drools.rules.   -  person Steve    schedule 23.02.2015
comment
Я определил пакет в моем файле Rule.drl как package drools.rules;, но теперь сообщение об ошибке просто меняется на Rule Compilation error The import drools.rules.ProcessData cannot be resolved   -  person Basit    schedule 23.02.2015
comment
Итак, ваш файл правил теперь: src/main/resources/drools/rules/ProcessData.drl?   -  person Steve    schedule 23.02.2015
comment
Я также немного обеспокоен тем, что ваш pom.xml импортирует 2 разные версии библиотек Drools. Он также устанавливает свойство для третьего, но, похоже, оно не используется.   -  person Steve    schedule 23.02.2015
comment
Мой файл правил не src/main/resources/drools/rules/Rule.drl, а в верхней части файла я объявил импорт как package drools.rules; . Нужно ли мне изменить имя файла с Rule на ProcessData?   -  person Basit    schedule 23.02.2015
comment
Кстати, правило скомпилировалось и активировалось до того, как вы добавили функцию?   -  person Steve    schedule 23.02.2015
comment
Нет, это дает мне ошибку, когда я пытаюсь инициализировать контекст весны, то есть в самой первой строке моей функции main(). В строке final ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); . Когда эта строка выполняется, я получаю ошибки.   -  person Basit    schedule 23.02.2015
comment
Я имел в виду - вы создали версию правила, которая работала без каких-либо вызовов глобальных переменных и т. д., прежде чем добавить это? Если вы разрабатываете приложение небольшими шагами, легче увидеть, какое изменение вызвало ошибку. Но сначала попробуйте сдачу @laune. Есть шанс, что это единственное, что вам нужно исправить.   -  person Steve    schedule 23.02.2015


Ответы (1)


Странно, что указана ошибка в функции processDataprocessData, которой нет в выложенном вами DRL, но есть другая ошибка, говорящая об отсутствии функции processData, которая фигурирует в DRL. Вы подделали код?

Но проблема просто в том, что вы не можете ссылаться на глобальную переменную внутри функции. Чтобы использовать глобальную переменную, передайте ее в качестве параметра.

function void processData(LicenseCredential licenseCredential,
                          CsvFileWriter learnerCsvFileWriter ){
    ....
}

rule ...
then
    System.out.println("Rule For 60 Days Called");      
    processData(licenseCredential, learnerCsvFileWriter);
end

Все претензии к команде Drools, пожалуйста!

person laune    schedule 23.02.2015
comment
А... Спасибо, чувак. Это работает. Большое спасибо Вам. Я думал, что, определив глобальную переменную, вы можете использовать ее где угодно, не передавая ее функциям. В любом случае еще раз спасибо. Но я ничего не делал. Я не знаю, почему в журналах отображается processDataprocessData,. Как я уже сказал, я слюни новичок. Но все ошибки ушли и теперь все работает отлично. Спасибо тебе и Стиву ;) :) - person Basit; 23.02.2015