Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-1186

Setting the planning variable nullable in nurserostering examples causes Drools NPE

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Critical
    • 7.0.0.Beta1
    • 6.2.0.Final, 6.3.0.Final
    • core engine
    • None
    • Hide

      1º Set the planning variable nullable in ShiftAssignment.java:

      @PlanningVariable(nullable = true, valueRangeProviderRefs = {"employeeRange"},
                  strengthComparatorClass = EmployeeStrengthComparator.class)
          public Employee getEmployee() {
              return employee;
          }
      

      2º Modify the EmployeeStrengthComparator class with this:

      @Override
          public int compare(Employee a, Employee b) {
              // El IF primero es para poder hacer nullable la planningVariable employee
              if (a == null || b == null)
                  return 0;
              else
              // TODO refactor to DifficultyWeightFactory and use getContract().getContractLineList()
              // to sum maximumValue and minimumValue etc
              return new CompareToBuilder()
                      .append(b.getWeekendLength(), a.getWeekendLength()) // Descending
                      .append(a.getId(), b.getId())
                      .toComparison();
          }
      

      3º Modify the ShiftAssignmentPillarPartSwapMoveFactory class, on line 67 with this:

      try { // Introducimos este bloque en el try-catch, para ignorar la NPE.
                  if (assignmentSequenceList.isEmpty()) {
                      AssignmentSequence assignmentSequence = new AssignmentSequence(employee, shiftAssignment);
                      assignmentSequenceList.add(assignmentSequence);
                  } else {
                      AssignmentSequence lastAssignmentSequence = assignmentSequenceList // getLast()
                              .get(assignmentSequenceList.size() - 1);
                      if (lastAssignmentSequence.belongsHere(shiftAssignment)) {
                          lastAssignmentSequence.add(shiftAssignment);
                      } else {
                          AssignmentSequence assignmentSequence = new AssignmentSequence(employee, shiftAssignment);
                          assignmentSequenceList.add(assignmentSequence);
                      }
                  }
                  } catch (NullPointerException ignorada) {
                  }
      

      4º Run the nurserostering example and try to resolve, Long05.xml, for example and you will get the NPE exception:

      Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Solving failed.
          at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.done(SolverAndPersistenceFrame.java:319)
          at javax.swing.SwingWorker$5.run(SwingWorker.java:737)
          at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
          at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
          at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
          at javax.swing.Timer.fireActionPerformed(Timer.java:312)
          at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
          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)
      Caused by: java.lang.NullPointerException
          at org.drools.core.phreak.RuleNetworkEvaluator.deleteChildLeftTuple(RuleNetworkEvaluator.java:778)
          at org.drools.core.phreak.RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(RuleNetworkEvaluator.java:771)
          at org.drools.core.phreak.PhreakNotNode.doRightUpdates(PhreakNotNode.java:355)
          at org.drools.core.phreak.PhreakNotNode.doNode(PhreakNotNode.java:73)
          at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:555)
          at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:536)
          at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:372)
          at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:332)
          at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:166)
          at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:123)
          at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:194)
          at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:73)
          at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1003)
          at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1346)
          at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1284)
          at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1303)
          at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1293)
          at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1274)
          at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:88)
          at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.calculateScore(DefaultSolverScope.java:116)
          at org.optaplanner.core.impl.phase.scope.AbstractPhaseScope.calculateScore(AbstractPhaseScope.java:124)
          at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.processMove(LocalSearchDecider.java:161)
          at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.doMove(LocalSearchDecider.java:149)
          at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(LocalSearchDecider.java:121)
          at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:72)
          at org.optaplanner.core.impl.solver.DefaultSolver.runPhases(DefaultSolver.java:214)
          at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:176)
          at org.optaplanner.examples.common.business.SolutionBusiness.solve(SolutionBusiness.java:316)
          at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:307)
          at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:297)
          at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
          at java.util.concurrent.FutureTask.run(FutureTask.java:262)
          at javax.swing.SwingWorker.run(SwingWorker.java:335)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
          at java.lang.Thread.run(Thread.java:744)
      
      Show
      1º Set the planning variable nullable in ShiftAssignment.java: @PlanningVariable(nullable = true , valueRangeProviderRefs = { "employeeRange" }, strengthComparatorClass = EmployeeStrengthComparator.class) public Employee getEmployee() { return employee; } 2º Modify the EmployeeStrengthComparator class with this: @Override public int compare(Employee a, Employee b) { // El IF primero es para poder hacer nullable la planningVariable employee if (a == null || b == null ) return 0; else // TODO refactor to DifficultyWeightFactory and use getContract().getContractLineList() // to sum maximumValue and minimumValue etc return new CompareToBuilder() .append(b.getWeekendLength(), a.getWeekendLength()) // Descending .append(a.getId(), b.getId()) .toComparison(); } 3º Modify the ShiftAssignmentPillarPartSwapMoveFactory class, on line 67 with this: try { // Introducimos este bloque en el try - catch , para ignorar la NPE. if (assignmentSequenceList.isEmpty()) { AssignmentSequence assignmentSequence = new AssignmentSequence(employee, shiftAssignment); assignmentSequenceList.add(assignmentSequence); } else { AssignmentSequence lastAssignmentSequence = assignmentSequenceList // getLast() .get(assignmentSequenceList.size() - 1); if (lastAssignmentSequence.belongsHere(shiftAssignment)) { lastAssignmentSequence.add(shiftAssignment); } else { AssignmentSequence assignmentSequence = new AssignmentSequence(employee, shiftAssignment); assignmentSequenceList.add(assignmentSequence); } } } catch (NullPointerException ignorada) { } 4º Run the nurserostering example and try to resolve, Long05.xml, for example and you will get the NPE exception: Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Solving failed. at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.done(SolverAndPersistenceFrame.java:319) at javax.swing.SwingWorker$5.run(SwingWorker.java:737) at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832) at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112) at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842) at javax.swing.Timer.fireActionPerformed(Timer.java:312) at javax.swing.Timer$DoPostEvent.run(Timer.java:244) 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) Caused by: java.lang.NullPointerException at org.drools.core.phreak.RuleNetworkEvaluator.deleteChildLeftTuple(RuleNetworkEvaluator.java:778) at org.drools.core.phreak.RuleNetworkEvaluator.unlinkAndDeleteChildLeftTuple(RuleNetworkEvaluator.java:771) at org.drools.core.phreak.PhreakNotNode.doRightUpdates(PhreakNotNode.java:355) at org.drools.core.phreak.PhreakNotNode.doNode(PhreakNotNode.java:73) at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:555) at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:536) at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:372) at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:332) at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:166) at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:123) at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:194) at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:73) at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1003) at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1346) at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1284) at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1303) at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1293) at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1274) at org.optaplanner.core.impl.score.director.drools.DroolsScoreDirector.calculateScore(DroolsScoreDirector.java:88) at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.calculateScore(DefaultSolverScope.java:116) at org.optaplanner.core.impl.phase.scope.AbstractPhaseScope.calculateScore(AbstractPhaseScope.java:124) at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.processMove(LocalSearchDecider.java:161) at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.doMove(LocalSearchDecider.java:149) at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(LocalSearchDecider.java:121) at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:72) at org.optaplanner.core.impl.solver.DefaultSolver.runPhases(DefaultSolver.java:214) at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:176) at org.optaplanner.examples.common.business.SolutionBusiness.solve(SolutionBusiness.java:316) at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:307) at org.optaplanner.examples.common.swingui.SolverAndPersistenceFrame$SolveWorker.doInBackground(SolverAndPersistenceFrame.java:297) at javax.swing.SwingWorker$1.call(SwingWorker.java:296) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at javax.swing.SwingWorker.run(SwingWorker.java:335) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang. Thread .run( Thread .java:744)
    • NEW
    • NEW

    Description

      If you set the planning variable to "nullable=true", firstable, causes a IllegalStateException.
      fixed that, causes the first NPE, and fixed that, causes other NPE unfixed:
      Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException:
      Caused by: java.lang.NullPointerException
      at org.drools.core.phreak.RuleNetworkEvaluator.deleteChildLeftTuple(RuleNetworkEvaluator.java:778)

      Attachments

        Issue Links

          Activity

            People

              mfusco@redhat.com Mario Fusco
              julio.bellon.aguilera Julio Bellon Aguilera (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: