OptaPlanner 域访问类型 Gizmo
OptaPlanner domainAccessType Gizmo
我正在尝试在我的求解器配置中使用 <domainAccessType>GIZMO</domainAccessType>
。
它似乎可以快速访问我的大部分变量,但它会为我的 @PlanningSolution
:
中的变量抛出异常
17:30:17.863 [main ] TRACE Model annotations parsed for solution VehicleRoutingSolution:
17:30:17.866 [main ] TRACE Entity Standstill:
17:30:17.866 [main ] TRACE Shadow variable nextVisit (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Entity Visit:
17:30:17.866 [main ] TRACE Genuine variable previousStandstill (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Shadow variable arrivalTime (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Shadow variable subShift (Fast access with generated bytecode)
Exception in thread "main" java.lang.IllegalStateException: Member (solverStatus) of class (org.acme.domain.VehicleRoutingSolution) is not public and domainAccessType is GIZMO.
Maybe put the annotations onto the public getter of the field.
Maybe use domainAccessType REFLECTION instead of GIZMO.
at org.optaplanner.core.impl.domain.common.accessor.gizmo.GizmoMemberDescriptor.<init>(GizmoMemberDescriptor.java:79)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionOrEntityDescriptor.getFieldsToSolutionFieldToMemberDescriptorMap(GizmoSolutionOrEntityDescriptor.java:63)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionOrEntityDescriptor.<init>(GizmoSolutionOrEntityDescriptor.java:39)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.lambda$createCloneSolutionRun(GizmoSolutionClonerImplementor.java:294)
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.createCloneSolutionRun(GizmoSolutionClonerImplementor.java:293)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.defineClonerFor(GizmoSolutionClonerImplementor.java:157)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.createClonerFor(GizmoSolutionClonerImplementor.java:200)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerFactory.build(GizmoSolutionClonerFactory.java:31)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.initSolutionCloner(SolutionDescriptor.java:601)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.afterAnnotationsProcessed(SolutionDescriptor.java:545)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.buildSolutionDescriptor(SolutionDescriptor.java:126)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolutionDescriptor(DefaultSolverFactory.java:160)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildScoreDirectorFactory(DefaultSolverFactory.java:133)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolver(DefaultSolverFactory.java:87)
at org.optaplanner.core.impl.solver.DefaultSolverManager.validateSolverFactory(DefaultSolverManager.java:69)
at org.optaplanner.core.impl.solver.DefaultSolverManager.<init>(DefaultSolverManager.java:58)
at org.optaplanner.core.api.solver.SolverManager.create(SolverManager.java:111)
at org.optaplanner.core.api.solver.SolverManager.create(SolverManager.java:84)
这是我正在使用的规划解决方案:
@PlanningSolution
class VehicleRoutingSolution {
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "visitRange")
lateinit var visitList: List<Visit>
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "subShiftRange")
lateinit var subShiftList: List<SubShift>
private var solverStatus: SolverStatus? = null
fun getSolverStatus(): SolverStatus? {
return solverStatus
}
fun setSolverStatus(solverStatus: SolverStatus?) {
this.solverStatus = solverStatus
}
private var score: SimpleLongScore? = null
@PlanningScore
fun getScore(): SimpleLongScore? {
return score
}
fun setScore(score: SimpleLongScore?) {
this.score = score
}
// No-arg constructor required for OptaPlanner
constructor() {}
constructor(subShiftList: List<SubShift>, visitList: List<Visit>) {
this.subShiftList = subShiftList
this.visitList = visitList
}
}
solverStatus
甚至没有注释,所以我不明白为什么它会抱怨这个。
奇怪的是,如果我将 score
变量部分放在 solverStatus
部分之上,它会抱怨 score
不是 public
,而 getter显然是。
知道这里发生了什么吗?
无法在 Quarkus 中重现。看到 https://github.com/kiegroup/optaplanner-quickstarts/tree/stable/technology/kotlin-quarkus for an example of using OptaPlanner with Kotlin in Quarkus. I tested changing the the fields of TimeTable 到 private,它按预期工作。
在 Quarkus 之外,这种行为是预期的。当使用域访问类型 GIZMO 时,将为域生成成员访问器和自定义解决方案克隆器。自定义解决方案克隆器要求所有字段为 public; public getters/setters 未被使用,因为它们不能保证简单(它们可以进行抛出异常的验证检查,或修改其他字段)。
我正在尝试在我的求解器配置中使用 <domainAccessType>GIZMO</domainAccessType>
。
它似乎可以快速访问我的大部分变量,但它会为我的 @PlanningSolution
:
17:30:17.863 [main ] TRACE Model annotations parsed for solution VehicleRoutingSolution:
17:30:17.866 [main ] TRACE Entity Standstill:
17:30:17.866 [main ] TRACE Shadow variable nextVisit (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Entity Visit:
17:30:17.866 [main ] TRACE Genuine variable previousStandstill (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Shadow variable arrivalTime (Fast access with generated bytecode)
17:30:17.866 [main ] TRACE Shadow variable subShift (Fast access with generated bytecode)
Exception in thread "main" java.lang.IllegalStateException: Member (solverStatus) of class (org.acme.domain.VehicleRoutingSolution) is not public and domainAccessType is GIZMO.
Maybe put the annotations onto the public getter of the field.
Maybe use domainAccessType REFLECTION instead of GIZMO.
at org.optaplanner.core.impl.domain.common.accessor.gizmo.GizmoMemberDescriptor.<init>(GizmoMemberDescriptor.java:79)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionOrEntityDescriptor.getFieldsToSolutionFieldToMemberDescriptorMap(GizmoSolutionOrEntityDescriptor.java:63)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionOrEntityDescriptor.<init>(GizmoSolutionOrEntityDescriptor.java:39)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.lambda$createCloneSolutionRun(GizmoSolutionClonerImplementor.java:294)
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.createCloneSolutionRun(GizmoSolutionClonerImplementor.java:293)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.defineClonerFor(GizmoSolutionClonerImplementor.java:157)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerImplementor.createClonerFor(GizmoSolutionClonerImplementor.java:200)
at org.optaplanner.core.impl.domain.solution.cloner.gizmo.GizmoSolutionClonerFactory.build(GizmoSolutionClonerFactory.java:31)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.initSolutionCloner(SolutionDescriptor.java:601)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.afterAnnotationsProcessed(SolutionDescriptor.java:545)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.buildSolutionDescriptor(SolutionDescriptor.java:126)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolutionDescriptor(DefaultSolverFactory.java:160)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildScoreDirectorFactory(DefaultSolverFactory.java:133)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolver(DefaultSolverFactory.java:87)
at org.optaplanner.core.impl.solver.DefaultSolverManager.validateSolverFactory(DefaultSolverManager.java:69)
at org.optaplanner.core.impl.solver.DefaultSolverManager.<init>(DefaultSolverManager.java:58)
at org.optaplanner.core.api.solver.SolverManager.create(SolverManager.java:111)
at org.optaplanner.core.api.solver.SolverManager.create(SolverManager.java:84)
这是我正在使用的规划解决方案:
@PlanningSolution
class VehicleRoutingSolution {
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "visitRange")
lateinit var visitList: List<Visit>
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "subShiftRange")
lateinit var subShiftList: List<SubShift>
private var solverStatus: SolverStatus? = null
fun getSolverStatus(): SolverStatus? {
return solverStatus
}
fun setSolverStatus(solverStatus: SolverStatus?) {
this.solverStatus = solverStatus
}
private var score: SimpleLongScore? = null
@PlanningScore
fun getScore(): SimpleLongScore? {
return score
}
fun setScore(score: SimpleLongScore?) {
this.score = score
}
// No-arg constructor required for OptaPlanner
constructor() {}
constructor(subShiftList: List<SubShift>, visitList: List<Visit>) {
this.subShiftList = subShiftList
this.visitList = visitList
}
}
solverStatus
甚至没有注释,所以我不明白为什么它会抱怨这个。
奇怪的是,如果我将 score
变量部分放在 solverStatus
部分之上,它会抱怨 score
不是 public
,而 getter显然是。
知道这里发生了什么吗?
无法在 Quarkus 中重现。看到 https://github.com/kiegroup/optaplanner-quickstarts/tree/stable/technology/kotlin-quarkus for an example of using OptaPlanner with Kotlin in Quarkus. I tested changing the the fields of TimeTable 到 private,它按预期工作。
在 Quarkus 之外,这种行为是预期的。当使用域访问类型 GIZMO 时,将为域生成成员访问器和自定义解决方案克隆器。自定义解决方案克隆器要求所有字段为 public; public getters/setters 未被使用,因为它们不能保证简单(它们可以进行抛出异常的验证检查,或修改其他字段)。