小编典典

OptaPlanner的Drools规则不会在类路径上与Spring Boot的devtools一起触发,因此得分为零

spring-boot

我让optaplanner正确地使用了流口水的规则。“突然”,在我进行了一些更改之后,Optaplanner不再将我的事实放到流口水的kSession中。

我进行了一些日志记录,发现optaplanner在我的解决方案上调用了getProblemFacts()方法,该方法返回的列表大小大于0。

我编写了一个DRL规则,以简单地计算事实并记录这些计数(该规则经过了单元测试,当我将对象放入ksession时效果很好)。我也坚信optaplanner不会将事实存储在工作记忆中。

ConstructionHeuristics阶段可以很好地终止(并且确实可以完成工作,因为在此阶段之后,我的PlaningVariables不再为null)。我只有在LocalSearch开始时才遇到问题。

不知道如何/在何处进一步搜索以了解问题。有任何想法吗?

我有一个建议:我使用<scanAnnotatedClasses/>并有此问题。如果我“手动”使用两个类<solutionClass/><entityClass/>那么我将得到一个反射错误:

Exception in thread "Solver" java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.optaplanner.core.impl.domain.common.accessor.BeanPropertyMemberAccessor.executeGetter(BeanPropertyMemberAccessor.java:67)
    at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.extractEntityCollection(SolutionDescriptor.java:626)
    at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.getEntityCount(SolutionDescriptor.java:489)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.cloneSolution(FieldAccessingSolutionCloner.java:200)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.cloneSolution(FieldAccessingSolutionCloner.java:70)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:147)
    at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:197)
    at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:195)
    at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:175)
    at ****.services.impl.SolverServiceImpl.lambda$0(SolverServiceImpl.java:169)

阅读 690

收藏
2020-05-30

共1个答案

小编典典

我正在使用spring dev工具自动在源文件中重新加载我的webapp uppon更改。

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- boot-devtools</artifactId> <optional>true</optional> </dependency>

这就是问题。为了执行热重装,Spring会加载并监视项目的所有资源和类,RestartClassLoader而库(依赖项,例如Drools&Optaplanner)则由Base
ClassLoader加载(实际上是AppClassLoader)。因此存在问题。

要解决此问题,请配置spring dev工具以将Reools库文件连同项目的类一起加载到RestartClassLoader中: using-boot-
devtools-customizing-classload

所以我的问题不是很好的名字。Drools的工作内存不是空的,而是包含不是instanceof我的类的对象,因为它们不在同一个ClassLoader中。

为了理解这一点,我使用了以下规则:

rule "countProblemFacts"
when
    $nLectures : Long() from accumulate($lectures : Lecture(), count( $lectures ))
    $nCourses : Long() from accumulate($courses : Course(), count( $courses ))
    $nRooms : Long() from accumulate($rooms : Room(), count( $rooms ))
    $nPeriods : Long() from accumulate($periods : Period(), count( $periods ))
    $nObjects : Long() from accumulate($objects : Object(), count( $objects ))
then
    DroolsUtil.log(drools, "Drools working memory");    
    DroolsUtil.log("Lectures:", $nLectures);
    DroolsUtil.log("Courses:", $nCourses);
    DroolsUtil.log("Rooms:", $nRooms);
    DroolsUtil.log("Periods:", $nPeriods);
    DroolsUtil.log("Objects:", $nObjects);
    DroolsUtil.log(drools, "Total", ($nLectures + $nCourses + $nRooms + $nPeriods), "objects");
end

$ nObjects计数为12,所有其他计数为0,因为类不是“相同的”。

2020-05-30