我正在使用 OptaPlanner
9.37.0.Final
与 quarkus 3.1.3.Final
和 Kotlin 1.8.21
来解决 VRP。
当我运行
quarkusDev
时,我当前的设置运行得很好,但是当我运行 @QuarkusTest
时,我得到以下 ClassCastException
,暗示类加载的某些内容可能会被破坏。
java.lang.ClassCastException: class com.cargonexx.vehiclerouting.domain.LoadJob$OptaPlanner$MemberAccessor$Field$arrivalTime cannot be cast to class org.optaplanner.core.impl.domain.common.accessor.MemberAccessor (com.cargonexx.vehiclerouting.domain.LoadJob$OptaPlanner$MemberAccessor$Field$arrivalTime is in unnamed module of loader 'OptaPlanner Gizmo SolutionCloner ClassLoader' @611d16c9; org.optaplanner.core.impl.domain.common.accessor.MemberAccessor is in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @319988b0)
at org.optaplanner.core.impl.domain.common.accessor.gizmo.GizmoMemberAccessorImplementor.createInstance(GizmoMemberAccessorImplementor.java:118)
at org.optaplanner.core.impl.domain.common.accessor.gizmo.GizmoMemberAccessorImplementor.createAccessorFor(GizmoMemberAccessorImplementor.java:112)
at org.optaplanner.core.impl.domain.common.accessor.gizmo.GizmoMemberAccessorFactory.buildGizmoMemberAccessor(GizmoMemberAccessorFactory.java:40)
at org.optaplanner.core.impl.domain.common.accessor.MemberAccessorFactory.buildMemberAccessor(MemberAccessorFactory.java:38)
at org.optaplanner.core.impl.domain.common.accessor.MemberAccessorFactory.lambda$buildAndCacheMemberAccessor$0(MemberAccessorFactory.java:125)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
at org.optaplanner.core.impl.domain.common.accessor.MemberAccessorFactory.buildAndCacheMemberAccessor(MemberAccessorFactory.java:124)
at org.optaplanner.core.impl.domain.entity.descriptor.EntityDescriptor.processPlanningVariableAnnotation(EntityDescriptor.java:239)
at org.optaplanner.core.impl.domain.entity.descriptor.EntityDescriptor.processAnnotations(EntityDescriptor.java:154)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.buildSolutionDescriptor(SolutionDescriptor.java:106)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.buildSolutionDescriptor(DefaultSolverFactory.java:147)
at org.optaplanner.core.impl.solver.DefaultSolverFactory.<init>(DefaultSolverFactory.java:69)
at org.optaplanner.core.api.solver.SolverFactory.create(SolverFactory.java:106)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider.solverFactory(DefaultOptaPlannerBeanProvider.java:46)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverFactory_3b1fa4ff0a3de7781ba3e1239701086bba97ef14_Bean.doCreate(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverFactory_3b1fa4ff0a3de7781ba3e1239701086bba97ef14_Bean.create(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverFactory_3b1fa4ff0a3de7781ba3e1239701086bba97ef14_Bean.get(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverFactory_3b1fa4ff0a3de7781ba3e1239701086bba97ef14_Bean.get(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverManager_d6636211e93ca3985f0495d972987bdadf803f37_Bean.doCreate(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverManager_d6636211e93ca3985f0495d972987bdadf803f37_Bean.create(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverManager_d6636211e93ca3985f0495d972987bdadf803f37_Bean.get(Unknown Source)
at org.optaplanner.quarkus.bean.DefaultOptaPlannerBeanProvider_ProducerMethod_solverManager_d6636211e93ca3985f0495d972987bdadf803f37_Bean.get(Unknown Source)
at com.cargonexx.vehiclerouting.rest.SolverResource_Bean.doCreate(Unknown Source)
at com.cargonexx.vehiclerouting.rest.SolverResource_Bean.create(Unknown Source)
at com.cargonexx.vehiclerouting.rest.SolverResource_Bean.create(Unknown Source)
at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:113)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:37)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:34)
at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:34)
at com.cargonexx.vehiclerouting.rest.SolverResource_Bean.get(Unknown Source)
at com.cargonexx.vehiclerouting.rest.SolverResource_Bean.get(Unknown Source)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:499)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:479)
at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:512)
at io.quarkus.arc.impl.ArcContainerImpl$2.get(ArcContainerImpl.java:287)
at io.quarkus.arc.impl.ArcContainerImpl$2.get(ArcContainerImpl.java:284)
at io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:46)
at io.quarkus.resteasy.reactive.common.runtime.ArcBeanFactory.createInstance(ArcBeanFactory.java:27)
at org.jboss.resteasy.reactive.server.handlers.InstanceHandler.handle(InstanceHandler.java:26)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:139)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
我有一个
PlanningEntity
,大致如下:
@PlanningEntity
class LoadJob {
@PlanningId lateinit var id: String
@InverseRelationShadowVariable(sourceVariableName = "tour") //
var vehicle: Vehicle? = null
@PreviousElementShadowVariable(sourceVariableName = "tour") //
var previousLoadJob: LoadJob? = null
@NextElementShadowVariable(sourceVariableName = "tour") //
var nextLoadJob: LoadJob? = null
@JvmField
@ShadowVariable(
variableListenerClass = ArrivalTimeUpdateListener::class,
sourceVariableName = "vehicle"
)
@ShadowVariable(
variableListenerClass = ArrivalTimeUpdateListener::class,
sourceVariableName = "previousLoadJob"
)
var arrivalTime: LocalDateTime? = null
}
用于
PlanningListVariable
类中的 Vehicle
:
@PlanningEntity
class Vehicle {
@PlanningId lateinit var planningId: String
@PlanningListVariable lateinit var tour: MutableList<LoadJob>
}
两者都是
PlanningSolution
的一部分
@PlanningSolution
class TourPlan {
lateinit var id: String
@PlanningEntityCollectionProperty //
lateinit var vehicles: List<Vehicle>
@ValueRangeProvider
@ProblemFactCollectionProperty //
lateinit var loadJobs: List<LoadJob>
@PlanningScore //
var score: HardMediumSoftLongScore? = null
@ConstraintConfigurationProvider
var constraintConfiguration: TourPlanConstraintConfiguration = TourPlanConstraintConfiguration()
constructor() // required for optaplanner
}
还有其他人遇到过这样的问题吗?此问题有任何已知的解决方法或修复吗?
我现在已经使用此设置工作了近一个月,但从长远来看,不运行任何
QuarkusTest
可能是不可行的,因为它们在当前设置中被破坏了。
注释
REFLECTION
而不是 GIZMO
进行 optaplanner 域访问时,我没有这个问题。然而,由于反射速度较慢,正如 optaplanner 文档也提到的那样,我希望能够使用 GIZMO
来提高性能,而不必使用不同的配置进行测试和常规构建我相信这个问题已在 Timefold 1.0.0 中得到修复。 (问题描述还包含一个解决方法。)请检查该版本,如果您的情况仍未解决,请提出问题,最好使用重现器。
OptaPlanner 是否会解决这个问题以及何时解决,我不知道。