Search code examples
optaplanner

Error in OptaPlanner when multithreading (External object cannot be looked up)


I have developped an optimization module using OptaPlanner but have encountered an error when multithreading. Note that the module works when multithreading is disabled. I tried several OptaPlanner versions (8.4, 8.1, 7.51) and different JDKs (16 and 14).

I used a simple solver configuration file Sover config

**

My planning entity is also straghtforward :

**

@PlanningSolution public class SuccessPromotion  {
    
    @ProblemFactCollectionProperty
    public ArrayList<RCT> rcts;
    @PlanningEntityCollectionProperty
    public ArrayList<RCT_Planning> rcts_promos;
    @ValueRangeProvider(id = "availablePromotion")
    @ProblemFactCollectionProperty
    public List<int[]> promotions;
    @PlanningScore
    public HardSoftScore score;
    @PlanningId
    public String name; //Constructors //Getter & Setter }

** The error I get is as follows : **

Exception in thread "main" java.lang.IllegalStateException: The move thread with moveThreadIndex (3) has thrown an exception. Relayed here in the parent thread. at org.optaplanner.core.impl.heuristic.thread.OrderByMoveIndexBlockingQueue.take(OrderByMoveIndexBlockingQueue.java:147) at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.forageResult(MultiThreadedLocalSearchDecider.java:188) at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.decideNextStep(MultiThreadedLocalSearchDecider.java:159) at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:71) at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:99) at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:189) at test.RealSolver.main(RealSolver.java:140) Caused by: java.lang.IllegalArgumentException: The externalObject ([I@5ce1e52a) cannot be looked up. Some functionality, such as multithreaded solving, requires this ability. Maybe add an @PlanningId annotation on an identifier property of the class (class [I). Or otherwise, maybe change the @PlanningSolution annotation's LookUpStrategyType (not recommended). at org.optaplanner.core.impl.domain.lookup.NoneLookUpStrategy.lookUpWorkingObject(NoneLookUpStrategy.java:44) at org.optaplanner.core.impl.domain.lookup.LookUpManager.lookUpWorkingObject(LookUpManager.java:76) at org.optaplanner.core.impl.score.director.AbstractScoreDirector.lookUpWorkingObject(AbstractScoreDirector.java:512) at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:83) at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:31) at org.optaplanner.core.impl.heuristic.thread.MoveThreadRunner.run(MoveThreadRunner.java:140) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) **


Solution

  • Your error message is

    The externalObject ([I@5ce1e52a) cannot be looked up. Some functionality, such as multithreaded solving, requires this ability. Maybe add an @PlanningId annotation on an identifier property of the class (class [I).
    

    That class[I talks about your planning value class (int[]), not your planning entity class (ArrayList<RCT_Planning>).

    The planning value class int[] is neither immutable, nor has a @PlanningId, so it can't rebase it easily to another thread (although in theory it could copy it, it doesn't do so at the moment). The error message could be better.

    Workaround: wrap int[] in a planning value class.