-
Bug
-
Resolution: Done
-
Major
-
6.0.1.Final
-
None
The problem is in the example itself, not in optaplanner-core.
The ProblemFactChange implementation removes a Computer from the computerList, but because the computerList isn't cloned (normal planning clone semantics do not clone problem facts), that's the same List instance in the workingSolution as it is in the bestSolution (of the last BestSolutionEvent) and therefore the same as in the swing UI's guiSolution.
This paves the path for a race condition that causes an NPE, because - although the Computer should still exists in the bestSolution - it has already been removed from the workingSolution and as a side effect also been removed in the bestSolution.
2014-02-19 14:21:33,745 [pool-2-thread-1] DEBUG Step index (27), time spent (3168), score (0hard/-126640soft), best score (0hard/-126640soft), accepted/selected move count (1000/1061) for picked step (Process 150->[CloudComputer-75] <=> Process 87->[CloudComputer-72]). ... 2014-02-19 14:21:33,779 [AWT-EventQueue-0] INFO Scheduling delete of computer ([CloudComputer-1]). ... 2014-02-19 14:21:33,780 [pool-2-thread-1] INFO Phase (1) localSearch ended: step total (30), time spent (3203), best score (0hard/-126450soft). 2014-02-19 14:21:33,786 [pool-2-thread-1] INFO Real-time problem fact changes done: step total (1), new uninitialized best score (0hard/-125790soft). 2014-02-19 14:21:33,792 [pool-2-thread-1] INFO Solving restarted: time spent (3215), score (null), new best score (0hard/-125790soft), random (JDK with seed 0). ... Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at org.optaplanner.examples.cloudbalancing.swingui.CloudBalancingPanel.updatePanel(CloudBalancingPanel.java:186) at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame.bestSolutionChanged(SolverAndPersistenceFrame.java:121) at org.optaplanner.examples.common.business.SolutionBusiness$1$1.run(SolutionBusiness.java:197) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733) at java.awt.EventQueue.access$200(EventQueue.java:103) at java.awt.EventQueue$3.run(EventQueue.java:694) at java.awt.EventQueue$3.run(EventQueue.java:692) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:703) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) ... 2014-02-19 14:21:33,862 [pool-2-thread-1] DEBUG Step index (2), time spent (3285), score (0hard/-126060soft), best score (0hard/-126060soft), accepted/selected move count (1000/1009) for picked step (Process 51->[CloudComputer-72] <=> Process 169->[CloudComputer-85]).