Scala 编译器错误 : package api does not have a member materializeWeakTypeTag

标签 scala intellij-idea akka scalatest

我是 scala 的新手,所以我已经准备好接受我做错了什么!

我正在玩 Akka,并使用 scalatest 和 akka-testkit 进行测试。这是我的 build.sbt 配置

name := """EventHub"""

version := "1.0"

scalaVersion := "2.10.3"

libraryDependencies ++= Seq(
  "com.typesafe.akka" % "akka-actor_2.10" % "2.2.3",
  "com.typesafe.akka" % "akka-testKit_2.10" % "2.2.3" % "test",
  "org.scalatest" % "scalatest_2.10.0-M4" % "1.9-2.10.0-M4-B2" % "test",
  "com.ning" % "async-http-client" % "1.8.1"
)

当我编译时,我收到一条我不理解的消息。我为此谷歌搜索并发现了相关的 scala 编译器问题和错误。我不知道这是不是我所看到的,或者我是否在某个地方犯了一个基本错误。这是输出的摘要(为简洁起见,我删除了很多“噪音”;如果需要,可以添加更多细节!):

scalac: 
     while compiling: /Users/robert/Documents/Programming/Scala/Projects/EventHub/src/test/scala/Hub/Subscription/SubscriberSpec.scala
        during phase: typer
     library version: version 2.10.3
    compiler version: version 2.10.3
...
...
== Expanded type of tree ==
TypeRef(
  TypeSymbol(
    class SubscriberSpec extends TestKit with WordSpec with BeforeAndAfterAll with ImplicitSender

  )
)
uncaught exception during compilation: scala.reflect.internal.FatalError

和:

scalac: Error: package api does not have a member materializeWeakTypeTag
scala.reflect.internal.FatalError: package api does not have a member materializeWeakTypeTag
    at scala.reflect.internal.Definitions$DefinitionsClass.scala$reflect$internal$Definitions$DefinitionsClass$$fatalMissingSymbol(Definitions.scala:1037)
    at scala.reflect.internal.Definitions$DefinitionsClass.getMember(Definitions.scala:1055)
    at scala.reflect.internal.Definitions$DefinitionsClass.getMemberMethod(Definitions.scala:1090)
    at scala.reflect.internal.Definitions$DefinitionsClass.materializeWeakTypeTag(Definitions.scala:518)
    at scala.tools.reflect.FastTrack$class.fastTrack(FastTrack.scala:34)
    at scala.tools.nsc.Global$$anon$1.fastTrack$lzycompute(Global.scala:493)
    at scala.tools.nsc.Global$$anon$1.fastTrack(Global.scala:493)
    at scala.tools.nsc.typechecker.Namers$Namer.methodSig(Namers.scala:1144)
    at scala.tools.nsc.typechecker.Namers$Namer.getSig$1(Namers.scala:1454)
    at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1466)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply$mcV$sp(Namers.scala:731)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:730)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1$$anonfun$apply$1.apply(Namers.scala:730)
    at scala.tools.nsc.typechecker.Namers$Namer.scala$tools$nsc$typechecker$Namers$Namer$$logAndValidate(Namers.scala:1499)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:730)
    at scala.tools.nsc.typechecker.Namers$Namer$$anonfun$monoTypeCompleter$1.apply(Namers.scala:729)
    at scala.tools.nsc.typechecker.Namers$$anon$1.completeImpl(Namers.scala:1614)
...
...

我正在使用 IntelliJ 作为 ide。有几个 scala 文件;一个包含 Actor ,另一个包含网络客户端:

package Hub.Subscription

import scala.concurrent.{Promise, Future}
import com.ning.http.client.{AsyncCompletionHandler, AsyncHttpClient, Response}


trait WebClient {
  def postUpdate(url: String, payload: Any, topic: String): Future[Int]
  def postUnSubscribe(url: String, topic: String): Future[Int]
}

case class PostUpdateFailed(status: Int) extends RuntimeException

object AsyncWebClient extends WebClient{

  private val client = new AsyncHttpClient

  override def postUpdate(url: String, payload: Any, topic: String): Future[Int] = {
    val request = client.preparePost(url).build()
    val result = Promise[Int]()
    client.executeRequest(request, new AsyncCompletionHandler[Response]() {
      override def onCompleted(response: Response) = {
        if (response.getStatusCode / 100 < 4)
          result.success(response.getStatusCode)
        else
          result.failure(PostUpdateFailed(response.getStatusCode))
        response
      }

      override def onThrowable(t: Throwable) {
        result.failure(t)
      }
    })
    result.future
  }

  override def postUnSubscribe(url: String, topic: String): Future[Int] = {
    val request = client.preparePost(url).build()
    val result = Promise[Int]
    client.executeRequest(request, new AsyncCompletionHandler[Response] {
      override def onCompleted(response: Response) = {
        if (response.getStatusCode / 100 < 4)
          result.success(response.getStatusCode)
        else
          result.failure(PostUpdateFailed(response.getStatusCode))
        response
      }

      override def onThrowable(t: Throwable) {
        result.failure(t)
      }
    })
    result.future
  }

  def shutdown(): Unit = client.close()
}

还有我的 Actor :

package Hub.Subscription

import akka.actor.Actor
import Hub.Subscription.Subscriber.{Failed, Update, UnSubscribe}
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executor

object Subscriber {
  object UnSubscribe
  case class Update(payload: Any)
  case class Failed(callbackUrl: String)
}

class Subscriber(callbackUrl: String, unSubscribeUrl: String, topic: String) extends Actor{

  implicit val executor = context.dispatcher.asInstanceOf[Executor with ExecutionContext]
  def client: WebClient = AsyncWebClient

  def receive = {
    case Update(payload) => doUpdate(payload)
    case UnSubscribe => doUnSubscribe
    case Failed(clientUrl) => //log?
  }

  def doUpdate(payload: Any): Unit = {
    val future = client.postUpdate(callbackUrl, payload, topic)
    future onFailure  {
      case err: Throwable => sender ! Failed(callbackUrl)
    }
  }

  def doUnSubscribe: Unit = {
    //tell the client that they have been un-subscribed
    val future = client.postUnSubscribe(unSubscribeUrl, topic)
    future onFailure {
      case err: Throwable => //log
    }
  }
}

最后是我的测试规范:

package Hub.Subscription

import akka.testkit.{ImplicitSender, TestKit}
import akka.actor.{ActorRef, Props, ActorSystem}
import org.scalatest.{WordSpec, BeforeAndAfterAll}
import scala.concurrent.Future
import scala.concurrent.duration._

object SubscriberSpec {

  def buildTestSubscriber(url: String, unSubscribeUrl: String, topic: String, webClient: WebClient): Props =
    Props(new Subscriber(url, unSubscribeUrl, topic) {
      override def client = webClient
    })

  object FakeWebClient extends WebClient {
    override def postUpdate(url: String, payload: Any, topic: String): Future[Int] = Future.successful(201)
    override def postUnSubscribe(url: String, topic: String): Future[Int] = Future.failed(PostUpdateFailed(500))
  }
}

class SubscriberSpec extends TestKit(ActorSystem("SubscriberSpec"))
  with WordSpec
  with BeforeAndAfterAll
  with ImplicitSender {

  import SubscriberSpec._

  "A subscriber" must {

    "forward the update to the callback url" in {
      val fakeClient = FakeWebClient
      val callbackUrl = "http://localhost:9000/UserEvents"
      val subscriber: ActorRef = system.actorOf(buildTestSubscriber(callbackUrl, "unSubscribeUrl", "aTopic", fakeClient))

      subscriber ! Subscriber.Update(Nil)

      within(200 millis) {
        expectNoMsg
      }
    }
  }

  override def afterAll(): Unit = {
    system.shutdown()
  }
}

在此先感谢您的帮助/指点!

更新:我应该注意到,如果我不包括测试规范,那么一切都很好。但是当我添加测试规范时,出现了上述错误。

最佳答案

顺便说一句,我刚刚意识到您正在使用为 2.10.0-M4 编译的 scalatest。

Scala 的最终版本不应该与相应的里程碑版本二进制兼容,因此可能会发生奇怪的事情,包括崩溃。

如果将 scalatest 的版本更改为 "org.scalatest"%% "scalatest"% "1.9.1",一切都会正常运行。

关于Scala 编译器错误 : package api does not have a member materializeWeakTypeTag,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21610848/

相关文章:

groovy - IntelliJ Groovy 版本

android - 与 Android Gradle 插件并行处理应用程序和外部库

spring - 匹配的通配符是严格的,但找不到元素 'batch:job' 的声明 - 仅在生产服务器上

Scala case语法理解

scala - 如何处理一系列 Akka Stream Sources?

scala - 是否可以提高akka调度器的准确性

linux - 如何使用 sbt-native-packager 将参数传递给覆盖的脚本?

scala - 如何自动生成一个函数以将密封的案例类系列与隐式实例相匹配?

scala - Playframework、scala 案例类和属性未找到

java - 使用 Java/Scala 将 Markdown 转换为 HTML