2

I have this code:

val task = (() => {
  lineStream
    .parallel()
    .forEach(((line: String) => {
      val key = extractKeyFromLine(line)
      val random = ThreadLocalRandom.current()
      val csvRecord = gson.toJson(CsvRecordDto(random.nextInt(24), line))
      val record = new StringRecord(topic, key, csvRecord)
      val prod = producer.get()
      prod.send(record, MessageCallback)
    }).asJava.asInstanceOf[Consumer[String]])
}).asJava
pool.submit(task).get()

The pool variable is a ForkJoinPool. The runtime complains that task is a Supplier and not a Callable.

The .asJava thing is from scala.compat.java8.FunctionConverters._.

How do I fix this in scala 2.11.7?

pavel_orekhov
  • 1,657
  • 2
  • 15
  • 37
  • Possible duplicate of [Scala single method interface implementation](https://stackoverflow.com/questions/22820352/scala-single-method-interface-implementation) – Alonso Dominguez Nov 30 '18 at 16:35

1 Answers1

4

You could try it with explicit type ascription:

val task = (( () => { 
  ...your code here 
}): java.util.concurrent.Callable[Unit])

or

val task: java.util.concurrent.Callable[Unit] = () => { ... }

and then hope that the SAM will figure out how to convert the closure into the Callable. If SAM didn't work back in 2.11.7 (don't know, didn't try), then you can always fall back to

val task = new java.util.concurrent.Callable[Unit]() { 
  def call(): Unit = { ... } 
}

IIRC, the SAM syntax should work for version 2.11.5 and above with the -Xexperimental flag.

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
  • Ok, first of all, you don't provide a type parameter for callable, and intellij complains about it. Second, when I compile your second example, I get an error, saying that there's a type mismatch, found: () => Unit, required: java.util.concurrent.Callable[Unit]. The third example I can't use, it's too bureaucratic. – pavel_orekhov Nov 30 '18 at 16:42
  • @hey_you Yeah, I confused `Callable` with the unparameterized `Runnable`. The syntax `val task: java.util.concurrent.Callable[Unit] = () => ()` definitely does work in 2.12. If the second proposal doesn't work in this older version, then it means that SAM is not supported, and you might have to fall back to the "bureaucratic" solution, or encapsulate it into a small helper method that takes a closure and returns a `callable`. – Andrey Tyukin Nov 30 '18 at 16:51
  • In 2.11 you need `-Xexperimental` scalac option (https://github.com/scala/scala/pull/3018). – Alexey Romanov Nov 30 '18 at 17:05
  • @AlexeyRomanov Thanks! Added the hint about `-Xexperimental`. Does this now look as if it should work? Don't want to install older scala versions now, and Scastie throws some `ResolutionException`s for no apparent reason... – Andrey Tyukin Nov 30 '18 at 17:12
  • 1
    I think it should, but I don't have the time to check it either. – Alexey Romanov Nov 30 '18 at 17:17