问题描述
我让optaplanner正确地使用了流口水的规则.突然",在我做了一些更改之后,Optaplanner不再将我的事实放到流口水的kSession中.
I got optaplanner working correctly with drools rules."Suddenly", after some change I did, Optaplanner does not put my facts in the drools kSession anymore.
我进行了一些日志记录,发现optaplanner在我的解决方案上调用了getProblemFacts()方法,该方法返回了一个大小大于0的列表.
I put some logging, and I see that optaplanner calls the getProblemFacts() method on my Solution, and this method returns a list with size > 0.
我编写了一个DRL规则,以简单地计算事实并记录这些计数(该规则已经过单元测试,当我将对象自己放入ksession时效果很好).我也坚信optaplanner不会将事实存储在工作记忆中.
I wrote a DRL rule to simply count the facts and log these counts (This rule is unit tested, and works well when I put the objects in the ksession myself). I am also convinced that optaplanner does not put the facts in the working memory.
ConstructionHeuristics阶段可以很好地终止(并且确实可以完成工作,因为在此阶段之后,我的PlaningVariables不再为null).我只有在LocalSearch开始时才遇到问题.
The ConstructionHeuristics phase terminates well (and does it's job, as my PlaningVariables are not null anymore after this phase). I got my issue only when LocalSearch begins.
不知道如何/在何处进一步搜索以了解问题.有什么想法吗?
Don't know how/where to search further to understand the issue. Any ideas?
我有一个建议:我使用<scanAnnotatedClasses/>
并遇到此问题.如果我使用<solutionClass/>
和<entityClass/>
手动"放置两个类,则会得到反射错误:
I have an advice: I use <scanAnnotatedClasses/>
and have this problem.If I put the two classes "manually" using <solutionClass/>
and <entityClass/>
then I get a reflection error:
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更改.
I am using the spring dev tools to auto-reload my webapp uppon changes in the source files.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional></dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional></dependency>
这是问题.为了执行热重装,春季的RestartClassLoader
装载并监视了项目的所有资源和类,但是库(依赖项,例如Drools& Optaplanner)由Base ClassLoader装载(实际上是AppClassLoader
).因此存在问题.
This is the issue. To perform hot reloading, all resources and classes of the project are loaded and watched by spring's RestartClassLoader
but the librairies (dependencies, e.g. Drools & Optaplanner) are loaded by the Base ClassLoader (in fact AppClassLoader
). Therefore the problems.
要解决此问题,请配置spring开发工具以将Reools库文件连同项目的类一起加载到RestartClassLoader中:使用-boot-devtools-customizing-classload
To fix it, configure spring dev tools to load Drools librairies in the RestartClassLoader, together with the project's classes:using-boot-devtools-customizing-classload
所以我的问题不是很好的名字. Drools的工作内存不是空的,而是包含不是instanceof
我的类的对象,因为它们不在同一个ClassLoader中.
So my question was not really good named. Drools working memory is not empty, but contains Objects that are no instanceof
my Classes, because not in the same ClassLoader.
要理解这一点,我使用了以下规则:
To understand this I used the following Rule:
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,因为这些类不是相同的".
$nObjects counts to 12, all others count to 0, as the Classes are not "the same".
这篇关于OptaPlanner的Drools规则不会在类路径上与Spring Boot的devtools一起触发,因此得分为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!