Closed
Description
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
totrait 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
Labels
No labels