Uploaded image for project: 'OptaPlanner'
  1. OptaPlanner
  2. PLANNER-2337

NullPointerException in NearbyDistanceMatrix.getDestination()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Minor Minor
    • 8.5.0.Final
    • 7.49.0.Final
    • optaplanner-core
    • None
    • 2021 Week 10-12 (from Mar 8)
    • 3
    • Undefined
    • NEW
    • NEW

      This issue, with OptaPlanner crashing with NullPointerException in NearbyDistanceMatrix.getDestination(), was originally described on the OptaPlanner mailing list at https://groups.google.com/g/optaplanner-dev/c/7TjeJVQQqhU . According to rsynek@redhat.com, this looks like a valid bug, so upon his request I am reporting the issue here.

      For code that reproduces the crash, please see the "custom/nearby-distance-crash" branch in the https://github.com/asaveljevs/optaplanner repository. It builds upon OptaPlanner 7.49.0 and in commit https://github.com/asaveljevs/optaplanner/commit/7bf86b18ed08e613d28433720faf964c76e12fa9 adds a customer change filter and some logging to see what is going on. For convenience and just in case something happens to the repository later, the same patch is also attached to this issue as nearby-distance-crash.patch.

      In the filter, for simplicity, only those customers that are not directly attached to a vehicle are accepted. This is artificial, but it allows to show the problem with minimal changes to the code. In our real life scenario, we had work orders that were composed of a short sequence of pickups followed by a short sequence of deliveries and we used the filter, for instance, to not accept single deliveries for consideration, as they cannot be moved by themselves if they have an associated pickup, and this is how we discovered the crash in June last year.

      In order to reproduce the crash, run the examples, select vehicle routing, open "cvrp-32customers" and start solving, after which it should soon crash. A log with the crash is attached here for convenience as vehicle-routing-1.zip. There we can see that the crash happened after CustomerChangeFilter.accept() on "Customer-22" returned "true" and we can see towards the top of the log that, when NearbyDistanceMatrix was constructed, CustomerChangeFilter.accept() on "Customer-22" returned "false". We can also observe there that CustomerNearbyDistanceMeter.getNearbyDistance() was not called for entities for which CustomerChangeFilter.accept() returned "false". As a result, these entities do not have an entry in NearbyDistanceMatrix and hence the crash.

      To summarize the issue, is CustomerChangeFilter meant to be called at every step? The patch above shows that it is called at every step. But then why is it used to filter out entities from NearbyDistanceMatrix in the very beginning? An entity that may not be suitable for a move in the beginning, may become suitable for a move later on. Therefore, if CustomerChangeFilter is meant to be called at every step and filter out entities based on the current situation, it seems incorrect to use it for the purposes of constructing NearbyDistanceMatrix in the beginning.

            rsynek@redhat.com Radovan Synek
            asaveljevs Aleksandrs Saveljevs
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: