2014-02-06 75 views
2

我是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() 
    } 
} 

預先感謝任何幫助/指針!

更新:我應該注意到,如果我不包含測試規範,那麼一切都很好。但是當我添加測試規範時,我會得到上面的錯誤。

+0

因此,在重新編寫測試以使用Specs2而不是scalatest之後,我可以將其編譯。但是,我仍然很想知道爲什麼我看到這些編譯器錯誤...! – RobertMS

+0

聽起來像是一個scalatest宏的問題。現在看看它。 –

+0

你可以上傳你的項目到github上嗎?麻煩編譯它與您提供的文件。 –

回答

1

順便說一句我剛剛意識到你正在使用編譯爲2.10.0-M4的scalatest。

Scala的最終版本不應該與相應的里程碑版本二進制兼容,所以可能會發生奇怪的事情,包括崩潰。

如果您將scalatest的版本更改爲"org.scalatest" %% "scalatest" % "1.9.1",那麼所有內容都可以正常工作。

+0

偉大 - 修復它!謝謝。 – RobertMS

相關問題