While trying to create a simple test case to reproduce cyclic object initialization problems in Scala, I accidentally created this example and one variant does terminate and the other not, while it only depends on the type of the used thread pool:
import scala.concurrent.Future
import scala.concurrent._
import scala.concurrent.duration._
object Base {
  val LeftElement = "Left"
  val RightElement = "Right"
  println("Base before: " + Thread.currentThread())
  val all = Set(Left, Right)
  println("Base after: " + Thread.currentThread())
}
object Left {
  println("Left before: " + Thread.currentThread())
  val basePath = Base.LeftElement
}
object Right {
  println("Right before: " + Thread.currentThread())
  val basePath = Base.RightElement
}
object Main extends App {
  // comment in and app does not finish:
  // implicit val execContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2))
  //Left before: Thread[pool-1-thread-1,5,main]
  //Base before: Thread[pool-1-thread-1,5,main]
  //Right before: Thread[pool-1-thread-1,5,main]
  //Base after: Thread[pool-1-thread-1,5,main]
  // comment in and app does finish
  //import scala.concurrent.ExecutionContext.Implicits.global
  // output:
  //Left before: Thread[ForkJoinPool-1-worker-29,5,main]
  //Base before: Thread[ForkJoinPool-1-worker-29,5,main]
  //Right before: Thread[ForkJoinPool-1-worker-29,5,main]
  //Base after: Thread[ForkJoinPool-1-worker-29,5,main]
  Await.result(Future(Left.basePath), 1.seconds)
  Await.result(Future(Right.basePath), 1.seconds)
}
Why is that?