我让optaplanner正常使用drools规则。 "突然之间,在我做了一些改变之后,Optaplanner不再把我的事实放在流氓kSession了。
我进行了一些日志记录,我看到optaplanner在我的Solution上调用了getProblemFacts()方法,并且此方法返回一个大小为>的列表。 0
我编写了一个DRL规则来简单地计算事实并记录这些计数(这个规则经过单元测试,当我自己将对象放入ksession时效果很好)。我也相信,optaplanner并没有把事实放在工作记忆中。
ConstructionHeuristics阶段很好地终止(并完成它的工作,因为我的PlaningVariables在此阶段之后不再为null)。我只在LocalSearch开始时才得到我的问题。
不知道如何/在哪里进一步搜索以了解问题。有什么想法吗?
我有一个建议:我使用<scanAnnotatedClasses/>
并遇到此问题。
如果我把两个班级&#34;手动&#34;使用<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)
答案 0 :(得分:4)
我正在使用spring dev工具在源文件中自动重新加载我的webapp uppon更改。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
这就是问题所在。要执行热重新加载,项目的所有资源和类都由spring RestartClassLoader
加载和监视,但是库类(依赖项,例如Drools&amp; Optaplanner)由Base ClassLoader加载(事实上AppClassLoader
) 。因此存在问题。
要修复它,请配置spring dev工具以在RestartClassLoader中加载Drools librairies以及项目的类: 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,因为类不是“相同”。
答案 1 :(得分:0)
在我的应用程序中,我到处都有
org.springframework.boot.devtools.restart.classloader.RestartClassLoader
那不是默认的类加载器,所以有正在进行的类加载魔法。根据你的评论,它与用于加载optaplanner类的类加载器不同。所以你需要提供你的类加载器:
Classloader classloader = TimeTable.class.getClassLoader();
... = SolverFactory.createFromXmlResource(".../solverConfig.xml", classloader);
可能需要升级到6.4.0.Beta2
,我上个月修复了一些高级类加载问题。
答案 2 :(得分:0)
该问题应在Drools 7.23.0.Final中解决。参见https://issues.jboss.org/browse/DROOLS-1540。