You need to enable JavaScript to run this app. Optaplanner 7.48迁移至8.3.0时Drools ExpressionTyper异常问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Optaplanner 7.48迁移至8.3.0时Drools ExpressionTyper异常问题咨询

OptaPlanner 版本迁移过程中的DRL规则兼容问题

迁移背景

项目从 OptaPlanner 7.48(对应依赖 Drools 7.48 版本)迁移至 OptaPlanner 8.3.0(对应依赖 Drools 7.50 版本)时,原有DRL规则无法正常运行,初步推断问题根源与 Drools 7.50 版本的规则解析逻辑变化相关。

迁移前可正常运行的DRL规则

rule "applyHomeTeamConstraints"
  enabled true
    when $f1: ProblemFixture(slot != null, $ht: homeTeam)
         $tu: ProblemSoftConstraint(this memberOf $ht.constraints,
                                  matches($f1.slot.dateTime) )
    then
        scoreHolder.penalize(kcontext, -$tu.getWeight());
end

异常表现

上述规则在 OptaPlanner 7.48/Drools 7.48 环境下可正常编译运行,切换到新版本环境后抛出定位信息极度模糊的异常,早期堆栈压缩状态下的报错内容为:

java.lang.IllegalStateException: There is an error in a scoreDrl or scoreDrlFile.
    at uk.me.selwyn_family.league.scheduler.solver.SolverTest.testBuildSeasonSolver(SolverTest.java:47)
Caused by: java.lang.UnsupportedOperationException
    at uk.me.selwyn_family.league.scheduler.solver.SolverTest.testBuildSeasonSolver(SolverTest.java:47)

排查过程

  • 逐行定位异常后,确认错误实际抛出位置为 org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper 类的第243行,对应源码逻辑为:
    Expression parentLeft = findLeftLeafOfNameExpr(halfPointFreeExpr.getParentNode().orElseThrow(UnsupportedOperationException::new));
    
  • 异常触发的直接原因是代码中获取的父节点对象为空,抛出的异常未携带任何规则解析的上下文信息,大幅增加排查成本。
  • 临时解决方案:在matches()方法调用前补充this.关键字,即可绕开解析异常,修改后的规则片段为:
    rule "applyHomeTeamConstraints"
      enabled true
        when $f1: ProblemFixture(slot != null, $ht: homeTeam)
             $tu: ProblemSoftConstraint(this memberOf $ht.constraints,
                                      this.matches($f1.slot.dateTime) )
        then
            scoreHolder.penalize(kcontext, -$tu.getWeight());
    end
    

核心待确认问题

  • 旧版本下不带this.的方法调用写法可正常运行,是否属于旧版本解析的兼容疏漏、本身不符合Drools语法规范,还是Drools 7.50 版本引入的解析bug?
  • 该场景下的编译报错信息缺失关键上下文,排查耗时极长,是否能优化错误提示的清晰度,让用户直接定位到规则内的具体语法问题?

关闭堆栈压缩后的完整异常栈

java.lang.IllegalStateException: There is an error in a scoreDrl or scoreDrlFile.
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryFactory.java:280)
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.decideMultipleScoreDirectorFactories(ScoreDirectorFactoryFactory.java:103)
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildScoreDirectorFactory(ScoreDirectorFactoryFactory.java:68)
    at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildScoreDirectorFactory(DefaultSolverFactory.java:116)
    at org.optaplanner.core.impl.solver.DefaultSolverFactory.getScoreDirectorFactory(DefaultSolverFactory.java:73)
    at org.optaplanner.core.api.score.ScoreManager.create(ScoreManager.java:59)
    at uk.me.selwyn_family.league.scheduler.solver.SeasonSolver.<init>(SeasonSolver.java:31)
    at uk.me.selwyn_family.league.scheduler.solver.SolverTest.testBuildSeasonSolver(SolverTest.java:47)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:696)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:882)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1189)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
    at org.testng.SuiteRunner.run(SuiteRunner.java:254)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
    at org.testng.TestNG.run(TestNG.java:1057)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:136)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeSingleClass(TestNGDirectoryTestSuite.java:112)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:145)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
Caused by: java.lang.UnsupportedOperationException
    at java.base/java.util.Optional.orElseThrow(Optional.java:408)
    at org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper.toTypedExpressionRec(ExpressionTyper.java:243)
    at org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper.toTypedExpression(ExpressionTyper.java:153)
    at org.drools.modelcompiler.builder.generator.drlxparse.ConstraintParser.getDrlxParseResult(ConstraintParser.java:174)
    at org.drools.modelcompiler.builder.generator.drlxparse.ConstraintParser.drlxParse(ConstraintParser.java:104)
    at org.drools.modelcompiler.builder.generator.visitor.pattern.PatternDSL.findAllConstraint(PatternDSL.java:139)
    at org.drools.modelcompiler.builder.generator.visitor.pattern.PatternDSL.buildPattern(PatternDSL.java:241)
    at org.drools.modelcompiler.builder.generator.visitor.ModelGeneratorVisitor.visit(ModelGeneratorVisitor.java:145)
    at org.drools.compiler.lang.descr.PatternDescr.accept(PatternDescr.java:303)
    at org.drools.modelcompiler.builder.generator.visitor.AndVisitor.visit(AndVisitor.java:50)
    at org.drools.modelcompiler.builder.generator.visitor.ModelGeneratorVisitor.visit(ModelGeneratorVisitor.java:86)
    at org.drools.modelcompiler.builder.generator.ModelGenerator.processRule(ModelGenerator.java:187)
    at org.drools.modelcompiler.builder.generator.ModelGenerator.generateModel(ModelGenerator.java:160)
    at org.drools.modelcompiler.builder.ModelBuilderImpl.compileKnowledgePackages(ModelBuilderImpl.java:284)
    at org.drools.modelcompiler.builder.ModelBuilderImpl.buildRules(ModelBuilderImpl.java:220)
    at org.drools.modelcompiler.builder.ModelBuilderImpl.postBuild(ModelBuilderImpl.java:130)
    at org.drools.compiler.builder.impl.CompositeKnowledgeBuilderImpl.build(CompositeKnowledgeBuilderImpl.java:115)
    at org.drools.compiler.builder.impl.CompositeKnowledgeBuilder.build(CompositeKnowledgeBuilder.java:99)
    at org.drools.compiler.kie.builder.impl.AbstractKieProject.buildKnowledgePackages(AbstractKieProject.java:268)
    at org.drools.compiler.kie.builder.impl.AbstractKieProject.buildKnowledgePackages(AbstractKieProject.java:216)
    at org.drools.compiler.kie.builder.impl.AbstractKieProject.verify(AbstractKieProject.java:80)
    at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildKieProject(KieBuilderImpl.java:277)
    at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:245)
    at org.drools.compiler.kie.builder.impl.KieBuilderImpl.buildAll(KieBuilderImpl.java:202)
    at org.kie.internal.utils.KieHelper.getKieContainer(KieHelper.java:100)
    at org.kie.internal.utils.KieHelper.build(KieHelper.java:82)
    at org.optaplanner.core.impl.score.director.ScoreDirectorFactoryFactory.buildDroolsScoreDirectorFactory(ScoreDirectorFactoryFactory.java:272)
    ... 36 more

内容的提问来源于stack exchange,提问作者Chris Selwyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 23:54:08