I've written a Monte Carlo player for the board game Nine Men's Morris. Everything is basically immutable. The program involves lots of futures (hundreds) and a lot of modifying immutable Maps. Sometimes I get a crash with the following exception:
java.lang.NullPointerException
at scala.collection.mutable.HashTable$class.elemHashCode(HashTable.scala:154)
at scala.collection.immutable.HashMap.elemHashCode(HashMap.scala:41)
at scala.collection.mutable.HashTable$class.findEntry(HashTable.scala:66)
at scala.collection.immutable.HashMap.findEntry(HashMap.scala:41)
at scala.collection.immutable.HashMap.undo$1(HashMap.scala:132)
at scala.collection.immutable.HashMap.undo$1(HashMap.scala:130)
at scala.collection.immutable.HashMap.makeCopy(HashMap.scala:154)
at scala.collection.immutable.HashMap.makeCopyIfUpdated(HashMap.scala:161)
at scala.collection.immutable.HashMap.update(HashMap.scala:66)
at scala.collection.immutable.Map$class.$plus(Map.scala:66)
at scala.collection.immutable.HashMap.$plus(HashMap.scala:41)
at morris.players.MapBasedMorrisBoard.applyMove(MapBasedMorrisBoard.scala:30)
at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:45)
at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:44)
at scala.actors.Reaction.run(Reaction.scala:78)
at scala.actors.FJTask$Wrap.run(Unknown Source)
at scala.actors.FJTaskRunner.scanWhileIdling(Unknown Source)
at scala.actors.FJTaskRunner.run(Unknown Source)
I'm only using immutable Maps, so I wonder whether this is caused by a bug in my own code or maybe a bug in the scala library. When looking at the trace you can see, that there are calls to mutable HashTable further down the stack. Maybe this is causing problems with concurrency?
The code inside my program, where the exception occurs is just adding another collection to an immutable Map:
myMap ++ (someInteger -> aValue)
Edit: The same program without concurrency runs flawlessly.