我是scala的新手,所以我很樂意接受我做錯了什麼!Scala編譯器錯誤:package api沒有成員materializeWeakTypeTag
我在玩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文件;一個包含一個演員,另一個是Web客戶端:
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()
}
我的演員:
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()
}
}
預先感謝任何幫助/指針!
更新:我應該注意到,如果我不包含測試規範,那麼一切都很好。但是當我添加測試規範時,我會得到上面的錯誤。
因此,在重新編寫測試以使用Specs2而不是scalatest之後,我可以將其編譯。但是,我仍然很想知道爲什麼我看到這些編譯器錯誤...! – RobertMS
聽起來像是一個scalatest宏的問題。現在看看它。 –
你可以上傳你的項目到github上嗎?麻煩編譯它與您提供的文件。 –