为什么我总是从drools得到意外的全局错误?

为什么我总是从drools得到意外的全局错误?,drools,kie,Drools,Kie,当我启动规则时,我犯了一个奇怪的错误。 错误详细信息如下所示 java.lang.RuntimeException: Unexpected global [validateResult] at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1209) at com.hikedu.backend.service.impl.signupproj

当我启动规则时,我犯了一个奇怪的错误。
错误详细信息如下所示

java.lang.RuntimeException: Unexpected global [validateResult]
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1209)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:190)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:204)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.signUp(SignUpProjectServiceImpl.java:102)
    at com.hikedu.backend.controller.ProjectApplicationRecordController.signUp(ProjectApplicationRecordController.java:94)
    at com.hikedu.backend.controller.ProjectApplicationRecordController$$FastClassBySpringCGLIB$$dc339407.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
我搜索了很多关于这个错误的信息。答案都是一样的——dsl文件必须declar全局,declar名称和路径必须与给定的代码一致 但是我一次又一次地确认我的dsl和我的代码没有发现任何错误

我试图将全局名称更改为另一个名称,但仍然出现错误

所以请帮帮我

这是我的dsl

import com.hikedu.backend.model.User;
import com.hikedu.backend.model.ProjectVersion;
import java.util.Map;
import com.hikedu.backend.dto.signupproject.ApplicationInfo
import java.util.Date
import java.sql.Timestamp

global com.hikedu.backend.dto.project.ProjectSignUpValidateResultDTO validateResult

rule "department not match"
no-loop
when
    $p : ProjectVersion()
    $u : User($p.applicationRequirements.departmentId not contains departmentOfJoined.id)
then
    validateResult.setPass(false);
    validateResult.setTheReasonOfUnPass("some reason");
end
我做了调试来检查会话的全局。下面是调试结果

我使用的drools版本是

下面是KieSessionBuilder.build方法

@Override
    public KieSession build(String dsl) {
        if (dsl == null) {
            throw new RuntimeException("Dsl cannot be null");
        }
        KieHelper helper = new KieHelper();
        helper.setClassLoader(getClass().getClassLoader());
        helper.addContent(dsl, ResourceType.DSL);
        KieBase base = helper.build();
        return base.newKieSession();
    }

谢谢大家。我的英语不好,请原谅。

我自己解决了这个错误。 以下是解决方案:

改变构建drl的方式

@Override
public KieSession build(String drl) {
    if (drl == null) {
        throw new RuntimeException("Drl cannot be null");
    }

    kieFileSystem.write("src/main/resources/" + drl.hashCode() + ".drl", kieServices.getResources().newReaderResource(new StringReader(drl)));
    KieBuilder builder = kieServices.newKieBuilder(kieFileSystem).buildAll();

    Results results = builder.getResults();
    if (results.hasMessages(Message.Level.ERROR)) {
        throw new IllegalStateException("##errors : " + results.getMessages());
    }

    KieContainer container = kieServices.newKieContainer(builder.getKieModule().getReleaseId());

    return container.newKieSession();
}
在我改变构建方式后,drl出现了另一个错误:

java.lang.RuntimeException: Illegal class for global. Expected [com.hikedu.backend.dto.project.ProjectSignUpValidateResultDTO], found [com.hikedu.backend.dto.project.ProjectSignUpValidateResultDTO].
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1211)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:190)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:204)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.signUp(SignUpProjectServiceImpl.java:102)
    at com.hikedu.backend.controller.ProjectApplicationRecordController.signUp(ProjectApplicationRecordController.java:94)
    at com.hikedu.backend.controller.ProjectApplicationRecordController$$FastClassBySpringCGLIB$$dc339407.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
这将确保drools和kie由devtools本身的类装入器装入。 然后错误被修复了

这是一些文件


我自己解决了这个错误。 以下是解决方案:

改变构建drl的方式

@Override
public KieSession build(String drl) {
    if (drl == null) {
        throw new RuntimeException("Drl cannot be null");
    }

    kieFileSystem.write("src/main/resources/" + drl.hashCode() + ".drl", kieServices.getResources().newReaderResource(new StringReader(drl)));
    KieBuilder builder = kieServices.newKieBuilder(kieFileSystem).buildAll();

    Results results = builder.getResults();
    if (results.hasMessages(Message.Level.ERROR)) {
        throw new IllegalStateException("##errors : " + results.getMessages());
    }

    KieContainer container = kieServices.newKieContainer(builder.getKieModule().getReleaseId());

    return container.newKieSession();
}
在我改变构建方式后,drl出现了另一个错误:

java.lang.RuntimeException: Illegal class for global. Expected [com.hikedu.backend.dto.project.ProjectSignUpValidateResultDTO], found [com.hikedu.backend.dto.project.ProjectSignUpValidateResultDTO].
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1211)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:190)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.validate(SignUpProjectServiceImpl.java:204)
    at com.hikedu.backend.service.impl.signupproject.SignUpProjectServiceImpl.signUp(SignUpProjectServiceImpl.java:102)
    at com.hikedu.backend.controller.ProjectApplicationRecordController.signUp(ProjectApplicationRecordController.java:94)
    at com.hikedu.backend.controller.ProjectApplicationRecordController$$FastClassBySpringCGLIB$$dc339407.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
这将确保drools和kie由devtools本身的类装入器装入。 然后错误被修复了

这是一些文件


聚会迟到了,但我也犯了同样的错误,只是原因不同。我将使用Drools 7.0.12的系统从使用无状态会话更改为有状态会话。在有状态会话中,Drools似乎正在检查是否至少在一个.drl文件中定义了全局。如果.drl文件中没有“全局”定义,则会引发意外的全局错误。在无状态会话中,不进行此类检查

聚会迟到了,但我也犯了同样的错误,只是原因不同。我将使用Drools 7.0.12的系统从使用无状态会话更改为有状态会话。在有状态会话中,Drools似乎正在检查是否至少在一个.drl文件中定义了全局。如果.drl文件中没有“全局”定义,则会引发意外的全局错误。在无状态会话中,不进行此类检查

如果在创建
KieBase
后进行调试,您是否在其中看到任何包和规则?如果没有,则规则甚至没有添加到
KieBase
。你为什么要用DSL而不是DRL?在我调试完KieBase后,发现角色、包和全局都是空的。原因是我需要将DRL文件内容作为字符串存储到数据库中,并在运行时构建它。我是新来的,我不知道使用DSL和DRL@EstebanAliverti谢谢你的答复。我将尝试将其构建为DRL。如果您在创建
KieBase
后进行调试,您是否在其中看到任何包和规则?如果没有,则规则甚至没有添加到
KieBase
。你为什么要用DSL而不是DRL?在我调试完KieBase后,发现角色、包和全局都是空的。原因是我需要将DRL文件内容作为字符串存储到数据库中,并在运行时构建它。我是新来的,我不知道使用DSL和DRL@EstebanAliverti谢谢你的答复。我将尝试将其构建为DRL。