【问题标题】:Why does it not recognize asScala method?为什么它不能识别 asScala 方法?
【发布时间】:2019-06-25 19:59:53
【问题描述】:

我有以下代码,但无法编译:

import akka.NotUsed
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
import akka.pattern.FutureRef
import akka.stream.scaladsl._
import akka.stream.typed.scaladsl.ActorMaterializer
import org.apache.kafka.clients.admin._
import scala.jdk.FutureConverters._


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

object KafkaDetectorActor {

  val create: Behavior[NotUsed] = Behaviors.setup { context =>
    implicit val system = context.system
    implicit val materializer = ActorMaterializer()
    implicit val dispatcher = context.system.dispatchers


    Behaviors.same
  }

  private def health(server: String)(implicit executor: ExecutionContext): Future[Boolean] = {
    val props = new Properties
    props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, server)
    props.put(AdminClientConfig.CONNECTIONS_MAX_IDLE_MS_CONFIG, "10000")
    props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, "5000")

        AdminClient
          .create(props)
          .listTopics()
          .names()
          .asScala

  }

其中names 返回KafkaFuture[java.util.Set[String]]

它无法识别asScala 方法。 scala.jdk.FutureConverters._ 库被导入。我做错了什么?

【问题讨论】:

  • 它也不起作用。@MarioGalic 你试过了吗?
  • 你使用 scala 2.13 吗?
  • 编译错误是什么?
  • value asScala is not a member of org.apache.kafka.common.KafkaFuture[java.util.Set[String]] [error] possible cause: maybe a semicolon is missing before value asScala? [error] .asScala
  • AdminClient 是一个 Java 库,names() 方法返回一个 Future。

标签: scala akka scala-java-interop


【解决方案1】:

scala.jdk.FutureConverters operate on CompletableFuture 所以先试试converting KafkaFutureCompletableFuture 就像这样

  implicit class KafkaFutureToCompletableFuture[T](kafkaFuture: KafkaFuture[T]) {
    def toCompletableFuture: CompletableFuture[T] = {
      val wrappingFuture = new CompletableFuture[T]
      kafkaFuture.whenComplete((value, throwable) => {
        if (throwable != null) {
          wrappingFuture.completeExceptionally(throwable)
        }
        else {
          wrappingFuture.complete(value)
        }
      })
      wrappingFuture
    }
  }

现在我们可以拨打toCompletableFuture.asScala。例如,

import scala.jdk.FutureConverters._
KafkaFuture.completedFuture(42).toCompletableFuture.asScala.foreach(println)

输出42。在你的情况下,尝试

AdminClient
  .create(props)
  .listTopics()
  .names()
  .toCompletableFuture
  .asScala

【讨论】:

  • 有什么理由不直接将转换定义为 Scala Future
【解决方案2】:

正如Alexey Romanov 建议的那样,您可以直接转换为 Scala 的 Future:

   implicit class KafkaFutureEx[T](kafkaFuture: KafkaFuture[T]) {
    val p = Promise[T]
    kafkaFuture.whenComplete { (value, throwable) =>
      {
        if (throwable != null) {
          p.failure(throwable)
        } else {
          p.success(value)
        }
      }
    }

    def toScalaFuture = p.future
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多