Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

NullPointerException when trying to plan a journey with an arrival time #6102

Closed
miklcct opened this issue Sep 30, 2024 · 2 comments · Fixed by #6211
Closed

NullPointerException when trying to plan a journey with an arrival time #6102

miklcct opened this issue Sep 30, 2024 · 2 comments · Fixed by #6211

Comments

@miklcct
Copy link
Contributor

miklcct commented Sep 30, 2024

Expected behavior

The journey plan succeeds

Observed behavior

The journey plan fails with NullPointerException, with the following recorded when GraphQL log is enabled:

14:06:47.303 WARN [grizzly-1]  (LoggingDataFetcherExceptionHandler.java:19) Exception while fetching data (/plan) : Cannot invoke "org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent.boardWithFallback(java.util.function.Consumer, java.util.function.Consumer)" because the return value of "org.opentripplanner.raptor.rangeraptor.support.TimeBasedBoardingSupport.searchRegularTransfer(int, int, int, int)" is null
java.lang.NullPointerException: Cannot invoke "org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent.boardWithFallback(java.util.function.Consumer, java.util.function.Consumer)" because the return value of "org.opentripplanner.raptor.rangeraptor.support.TimeBasedBoardingSupport.searchRegularTransfer(int, int, int, int)" is null
        at org.opentripplanner.raptor.rangeraptor.standard.MinTravelDurationRoutingStrategy.boardWithRegularTransfer(MinTravelDurationRoutingStrategy.java:94)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.lambda$findTransitForRound$1(DefaultRangeRaptorWorker.java:245)
        at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor.findTransitForRound(PerformanceTimersForRaptor.java:53)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.findTransitForRound(DefaultRangeRaptorWorker.java:197)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.runRaptorForMinute(DefaultRangeRaptorWorker.java:166)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.lambda$route$0(DefaultRangeRaptorWorker.java:139)
        at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor.route(PerformanceTimersForRaptor.java:48)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.route(DefaultRangeRaptorWorker.java:128)
        at org.opentripplanner.raptor.service.HeuristicSearchTask.run(HeuristicSearchTask.java:116)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristicSearchTask(RangeRaptorDynamicSearch.java:224)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristicsSequentially(RangeRaptorDynamicSearch.java:208)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristics(RangeRaptorDynamicSearch.java:126)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.route(RangeRaptorDynamicSearch.java:71)
        at org.opentripplanner.raptor.RaptorService.route(RaptorService.java:38)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.route(TransitRouter.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.routeAndCleanupAfter(TransitRouter.java:99)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.route(TransitRouter.java:92)
        at org.opentripplanner.routing.algorithm.RoutingWorker.routeTransit(RoutingWorker.java:270)
        at org.opentripplanner.routing.algorithm.RoutingWorker.lambda$route$2(RoutingWorker.java:117)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
14:06:48.908 WARN [grizzly-4]  (LoggingDataFetcherExceptionHandler.java:19) Exception while fetching data (/plan) : Cannot invoke "org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent.boardWithFallback(java.util.function.Consumer, java.util.function.Consumer)" because the return value of "org.opentripplanner.raptor.rangeraptor.support.TimeBasedBoardingSupport.searchRegularTransfer(int, int, int, int)" is null
java.lang.NullPointerException: Cannot invoke "org.opentripplanner.raptor.spi.RaptorBoardOrAlightEvent.boardWithFallback(java.util.function.Consumer, java.util.function.Consumer)" because the return value of "org.opentripplanner.raptor.rangeraptor.support.TimeBasedBoardingSupport.searchRegularTransfer(int, int, int, int)" is null
        at org.opentripplanner.raptor.rangeraptor.standard.MinTravelDurationRoutingStrategy.boardWithRegularTransfer(MinTravelDurationRoutingStrategy.java:94)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.lambda$findTransitForRound$1(DefaultRangeRaptorWorker.java:245)
        at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor.findTransitForRound(PerformanceTimersForRaptor.java:53)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.findTransitForRound(DefaultRangeRaptorWorker.java:197)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.runRaptorForMinute(DefaultRangeRaptorWorker.java:166)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.lambda$route$0(DefaultRangeRaptorWorker.java:139)
        at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor.route(PerformanceTimersForRaptor.java:48)
        at org.opentripplanner.raptor.rangeraptor.DefaultRangeRaptorWorker.route(DefaultRangeRaptorWorker.java:128)
        at org.opentripplanner.raptor.service.HeuristicSearchTask.run(HeuristicSearchTask.java:116)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristicSearchTask(RangeRaptorDynamicSearch.java:224)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristicsSequentially(RangeRaptorDynamicSearch.java:208)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.runHeuristics(RangeRaptorDynamicSearch.java:126)
        at org.opentripplanner.raptor.service.RangeRaptorDynamicSearch.route(RangeRaptorDynamicSearch.java:71)
        at org.opentripplanner.raptor.RaptorService.route(RaptorService.java:38)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.route(TransitRouter.java:141)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.routeAndCleanupAfter(TransitRouter.java:99)
        at org.opentripplanner.routing.algorithm.raptoradapter.router.TransitRouter.route(TransitRouter.java:92)
        at org.opentripplanner.routing.algorithm.RoutingWorker.routeTransit(RoutingWorker.java:270)
        at org.opentripplanner.routing.algorithm.RoutingWorker.lambda$route$2(RoutingWorker.java:117)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
        at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)

Version of OTP used (exact commit hash or JAR name)

2.6.0

Data sets in use (links to GTFS and OSM PBF files)

combined_gtfs.zip

This GTFS contains only a single cable car route which operates in both direction Mon-Fri from 07:00 to 23:00.

Command line used to start OTP

java -jar otp-shaded.jar --load --serve .

Router config and graph build config JSON

otp-config.json

{
        "otpFeatures" : {
                "GtfsGraphQlApi": true,
                "ParallelRouting": true,
                "TransferConstraints" : false,
                "TransmodelGraphQlApi": true,
                "ActuatorAPI": false,
                "Co2Emissions": false,
                "FaresV2": false,
                "FlexRouting": true,
                "SandboxAPIGeocoder": false,
                "SandboxAPIParkAndRideApi": true
        }
}

router-config.json

{
  "routingDefaults": {
    "drivingDirection": "left",
    "locale": "en_GB",
    "numItineraries": 10,
    "searchWindow": "PT6H",
    "transferSlack": "PT30S",
    "waitReluctance": 1.76,
    "accessEgress": {
      "maxDuration": "PT2H"
    },
    "walk": {
      "boardCost": 300,
      "reluctance": 1.68
    },
    "wheelchairAccessibility": {
      "trip": {
        "onlyConsiderAccessible": false,
        "unknownCost": 600,
        "inaccessibleCost": 3600
      },
      "stop": {
        "onlyConsiderAccessible": false,
        "unknownCost": 600,
        "inaccessibleCost": 3600
      },
      "elevator": {
        "onlyConsiderAccessible": false
      },
      "inaccessibleStreetReluctance": 25,
      "maxSlope": 0.08333,
      "slopeExceededReluctance": 50,
      "stairsReluctance": 25
    }
  },
  "timetableUpdates": {
    "maxSnapshotFrequency": "PT5S"
  },
  "transit": {
    "searchThreadPoolSize": 4,
    "transferCacheRequests": [
      {
        "modes" : "WALK",
        "walk" : {
          "boardCost" : 300,
          "reluctance" : 1.68
        }
      }
    ]
  }
}

build-config.json

{
        "areaVisibility": true,
        "dataImportReport": true,
        "maxTransferDuration": "PT15M",
        "multiThreadElevationCalculations": true,
        "staticBikeParkAndRide" : true,
        "staticParkAndRide" : true,
        "stopConsolidationFile" : "consolidated-stops.csv",
        "subwayAccessTime": "1.0",
        "transitModelTimeZone": "Europe/London",
        "transitServiceEnd": "P3M",
        "transitServiceStart": "P-7D",
        "boardingLocationTags": ["naptan:AtcoCode", "naptan:NaptanCode"],
        "osmDefaults" : {
                "osmTagMapping" : "uk",
                "timeZone" : "Europe/London"
        },
        "transitFeeds" : [
                {
                        "type" : "gtfs",
                        "feedId" : "DfT",
                        "source" : "gtfs-dft.zip"
                },
                {
                        "type" : "gtfs",
                        "feedId" : "NR",
                        "source" : "national_rail_gtfs.zip"
                }
        ]
}

Steps to reproduce the problem

Plan a journey between the two cable car terminals on Monday before 07:00.

Note that the problem doesn't exist if a departure time is used.

@miklcct miklcct changed the title NullPointerException when trying to plan a journey NullPointerException when trying to plan a journey with an arrival time Sep 30, 2024
@miklcct
Copy link
Contributor Author

miklcct commented Oct 15, 2024

The problem appears when I search for an arrival on Monday 09:30, but not Wednesday 09:30.

@miklcct
Copy link
Contributor Author

miklcct commented Oct 30, 2024

The problematic code is in TripFrequencyAlightSearch.java which returns a null instead of empty.

I think that it should be merged with TripFrequencyBoardSearch.java as they share the same logic, just in different direction.

I will try to make a test case for that.

P.S. Issue updated with a minimal reproducible example. I may be able to work for a test and a fix soon.

miklcct added a commit to Jnction/OpenTripPlanner that referenced this issue Oct 30, 2024
miklcct added a commit to Jnction/OpenTripPlanner that referenced this issue Oct 30, 2024
miklcct added a commit to Jnction/OpenTripPlanner that referenced this issue Oct 30, 2024
miklcct added a commit to Jnction/OpenTripPlanner that referenced this issue Oct 31, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
1 participant