Null Pointer Exception on simulation startup while building feeder object

Gatling 3.2.1.

Getting a null pointer error during the construction of the feed node.

Things I’ve checked:

  • the path to the csv file is being constructed correctly

  • the file exists in target/scala_2.12/...

  • the contents of the file look fine with a cat ...

  • There are only about 300 rows in the csv file

  • It doesn’t look like any of the characters are non-ASCII

  • I tried adding an extra blank line at the end to make sure the last line had a newline

  • Also tried removing that last line

  • Originally, feed data didn’t include quotes around strings. Added them.
    I’m kind of out of ideas. What’s going on here:

[error] java.lang.NullPointerException
[error] at io.gatling.core.action.builder.FeedBuilder.newSingletonFeed(FeedBuilder.scala:38)
[error] at io.gatling.core.action.builder.FeedBuilder.$anonfun$build$1(FeedBuilder.scala:43)
[error] at scala.collection.mutable.MapLike.getOrElseUpdate(MapLike.scala:209)
[error] at scala.collection.mutable.MapLike.getOrElseUpdate$(MapLike.scala:206)
[error] at scala.collection.mutable.AbstractMap.getOrElseUpdate(Map.scala:82)
[error] at io.gatling.core.action.builder.FeedBuilder.build(FeedBuilder.scala:43)
[error] at io.gatling.core.structure.BuildAction.$anonfun$build$1(BuildAction.scala:28)
[error] at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
[error] at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
[error] at scala.collection.immutable.List.foldLeft(List.scala:89)
[error] at io.gatling.core.structure.BuildAction.build(BuildAction.scala:27)
[error] at io.gatling.core.structure.BuildAction.build$(BuildAction.scala:26)
[error] at io.gatling.core.structure.ScenarioBuilder.build(StructureBuilder.scala:52)
[error] at io.gatling.core.structure.PopulationBuilder.build(PopulationBuilder.scala:79)
[error] at io.gatling.core.scenario.SimulationParams.$anonfun$scenarios$1(Simulation.scala:192)
[error] at scala.collection.immutable.List.map(List.scala:286)
[error] at io.gatling.core.scenario.SimulationParams.scenarios(Simulation.scala:192)
[error] at io.gatling.app.Runner.run0(Runner.scala:91)
[error] at io.gatling.app.Runner.run(Runner.scala:60)
[error] at io.gatling.app.Gatling$.start(Gatling.scala:73)
[error] at io.gatling.app.Gatling$.fromArgs(Gatling.scala:46)
[error] at io.gatling.sbt.GatlingTask.liftedTree1$1(GatlingTask.scala:52)
[error] at io.gatling.sbt.GatlingTask.execute(GatlingTask.scala:51)
[error] at sbt.ForkMain$Run.lambda$runTest$1(ForkMain.java:304)
[error] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error] at java.lang.Thread.run(Thread.java:748)

Most likely an initialization order issue: you’re trying to use a reference that’s still null at this time because it hasn’t been initialized yet.

Here’s the basic simulation code.

class testLogin extends UnitTest {
  
  val path = "env/" + Test.environment + "/users.csv"
  val user = csv( path ).random

  def behavior =
    scenario( "Unit Test - Login Flow" )
      .feed( user )

And for reference, UnitTest looks like this:

trait UnitTest extends Simulation {
    
    def http_config = Default.httpConfig

    def behavior : ScenarioBuilder

    setUp( behavior.inject( atOnceUsers(1) ) )
        .protocols( http_config )
        .pauses(
            if ( Test.usePauses ) exponentialPauses
            else                  disabledPauses
        )
        .assertions(
            global.failedRequests.count.is(0)
        )
  
}


As far as I can tell, when the scenario is being composed, the values of path and user are both set.  And I tried .random and .random().  I get the same outcome either way.

Exactly what I said.

Before executing itself, testLogin’s constructor first calls parent UnitTest’s constructor that calls behavior that’s implemented in child and tries to use the user reference that hasn’t been initialized yet as testLogin’s constructor has run yet.

DOH! I get it. Note to self: Gotta define things as def instead of val in order to avoid that.