Skip to content

Cannot await a mapped Future in an object constructor #10782

Closed
@dxnxk-0

Description

@dxnxk-0

Hi folks, not sure if it's a bug or something we just don't understand, but we noticed we can't await a mapped future within an object constructor. We use scala 2.11.12 and Java SDK 1.8.0.101, but we also reproduced on the scala 2.10 and 2.12 lines.

Here is the code:

import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

object Foo {
  implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global
  val bar = Await.result(Future(0).flatMap(_ => Future(1)), 1000.milli)
}

object Test extends App {
  println(Foo.bar)
}

which results in:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at com.kds.one.common.Test$.delayedEndpoint$com$kds$one$common$Test$1(Test.scala:12)
	at com.kds.one.common.Test$delayedInit$body.apply(Test.scala:11)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at com.kds.one.common.Test$.main(Test.scala:11)
	at com.kds.one.common.Test.main(Test.scala)
Caused by: java.util.concurrent.TimeoutException: Futures timed out after [1000 milliseconds]
	at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:223)
	at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:227)
	at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190)
	at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
	at scala.concurrent.Await$.result(package.scala:190)
	at com.kds.one.common.Foo$.<init>(Test.scala:8)
	at com.kds.one.common.Foo$.<clinit>(Test.scala)
	... 11 more
java.lang.NoClassDefFoundError: Could not initialize class com.kds.one.common.Foo$
	at com.kds.one.common.Foo$$anonfun$2.apply(Test.scala:8)
	at com.kds.one.common.Foo$$anonfun$2.apply(Test.scala:8)
	at scala.util.Success$$anonfun$map$1.apply(Try.scala:237)
	at scala.util.Try$.apply(Try.scala:192)
	at scala.util.Success.map(Try.scala:237)
	at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
	at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:237)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:36)

Note that:

  • awaiting in the Test object -
  • or transforming the object Foo to trait Foo
    ...work like a charm.
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

trait Foo {
  implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global
  val bar = Await.result(Future(0).flatMap(_ => Future(1)), 1000.milli)
}

object Test extends App with Foo {
  println(bar)
}

Result:

1
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

object Foo {
  implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global
  val bar = Future(0).flatMap(_ => Future(1))
}

object Test extends App {
  println(Await.result(Foo.bar, 1000.milli))
}

Result:

1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions