我让optaplanner正确地使用了流口水的规则。“突然”,在我进行了一些更改之后,Optaplanner不再将我的事实放到流口水的kSession中。
我进行了一些日志记录,发现optaplanner在我的解决方案上调用了getProblemFacts()方法,该方法返回的列表大小大于0。
我编写了一个DRL规则,以简单地计算事实并记录这些计数(该规则经过了单元测试,当我将对象放入ksession时效果很好)。我也坚信optaplanner不会将事实存储在工作记忆中。
ConstructionHeuristics阶段可以很好地终止(并且确实可以完成工作,因为在此阶段之后,我的PlaningVariables不再为null)。我只有在LocalSearch开始时才遇到问题。
不知道如何/在何处进一步搜索以了解问题。有任何想法吗?
我有一个建议:我使用<scanAnnotatedClasses/>并有此问题。如果我“手动”使用两个类<solutionClass/>,<entityClass/>那么我将得到一个反射错误:
<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)
我正在使用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)。因此存在问题。
RestartClassLoader
AppClassLoader
要解决此问题,请配置spring dev工具以将Reools库文件连同项目的类一起加载到RestartClassLoader中: using-boot- devtools-customizing-classload
所以我的问题不是很好的名字。Drools的工作内存不是空的,而是包含不是instanceof我的类的对象,因为它们不在同一个ClassLoader中。
instanceof
为了理解这一点,我使用了以下规则:
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,因为类不是“相同的”。