lihaoyi / autowire

Macros for simple/safe RPCs between Scala applications, including ScalaJS/ScalaJVM
378 stars 50 forks source link

Sbt clean after adding a function to share Api #39

Open omidb opened 9 years ago

omidb commented 9 years ago

In the middle of development on ~re-start mode, if you add a function to the shared trait and override it in the server then you would get weird errors in the test time. To compile it correctly you have to do:

sbt 
clean
~re-start

The code that I am using is SPA tutorial (https://github.com/ochrons/scalajs-spa-tutorial)

lihaoyi commented 9 years ago

Can you give more detailed instructions of how to reproduce the issue?

omidb commented 9 years ago
git clone https://github.com/ochrons/scalajs-spa-tutorial.git
cd scalajs-spa-tutorial
sbt
~re-start

add this to shared/Api:

def dumbCall(s:String)

add this to jvm/ApiServices

override def dumbCall(s:String):Unit ={
    println(s)
  }

add this to client/component.Motad.scala in refresh method:

AjaxClient[Api].dumbCall("mooo").call()
      .foreach(message => "mooo")

now open http://localhost:8080/ and hit Update button you will see errors like these in server terminal:

8. Waiting for source changes... (press enter to interrupt)
sharedProjectJVM Listening for transport dt_socket at address: 5111
sharedProjectJVM [INFO] [07/22/2015 20:35:09.144] [SPA-akka.actor.default-dispatcher-4] [akka://SPA/user
/IO-HTTP/listener-0] Bound to /0.0.0.0:8083
sharedProjectJVM ClientLog: [{"logger":"Log","timestamp":1437622521852,"level":"INFO","url":"http://loca
lhost:8083/","message":"This message goes to server as well"}]
sharedProjectJVM Sending 4 Todo items
sharedProjectJVM [ERROR] [07/22/2015 20:35:22.076] [SPA-akka.actor.default-dispatcher-14] [akka://SPA/us
er/simple-service-actor] Error during processing of request HttpRequest(POST,http://localhost:8083/api/s
patutorial/shared/Api/dumbCall,List(Cookie: JSESSIONID=17t0mwi2aji8qnd6t7fvwsi50; PLAY_SESSION=8b8af9d7c
fa037c1917fe215f6d3f9d9858743e3-csrfToken=ff6b85caf469c613b000afdbb78dc921db16bc4b-1434055406859-5e6aad7
b16369ea26561e416&hangman=%7B%22level%22%3A5%2C%22word%22%3A%22LIABLE%22%2C%22guess%22%3A%5B%22G%22%5D%2
C%22misses%22%3A1%7D; gsScrollPos=0, Accept-Language: en-US, en;q=0.8, fa;q=0.6, ro;q=0.4, Accept-Encodi
ng: gzip, deflate, Referer: http://localhost:8083/, Content-Type: application/octet-stream, User-Agent:
Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/53
7.36, Origin: http://localhost:8083, Cache-Control: max-age=0, Content-Length: 1400, Connection: keep-al
ive, Host: localhost:8083),HttpEntity(application/octet-stream,☺☺s♣♦mooo

                                           ...),HTTP/1.1)
sharedProjectJVM scala.MatchError: Request(List(spatutorial, shared, Api, dumbCall),Map(s -> java.nio.He
apByteBufferR[pos=0 lim=5 cap=1396])) (of class autowire.Core$Request)
sharedProjectJVM        at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:253)
sharedProjectJVM        at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:251)
sharedProjectJVM        at spatutorial.server.MainApp$$anonfun$main$1$$anonfun$apply$2$$anonfun$apply$4$
$anonfun$apply$5$$anonfun$1.applyOrElse(MainApp.scala:58)
sharedProjectJVM        at spatutorial.server.MainApp$$anonfun$main$1$$anonfun$apply$2$$anonfun$apply$4$
$anonfun$apply$5$$anonfun$1.applyOrElse(MainApp.scala:58)
sharedProjectJVM        at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)

sharedProjectJVM        at spatutorial.server.MainApp$$anonfun$main$1$$anonfun$apply$2$$anonfun$apply$4$
$anonfun$apply$5.apply(MainApp.scala:58)
sharedProjectJVM        at spatutorial.server.MainApp$$anonfun$main$1$$anonfun$apply$2$$anonfun$apply$4$
$anonfun$apply$5.apply(MainApp.scala:56)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(R
outeConcatenation.scala:30)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(R
outeConcatenation.scala:29)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1$$anonfu
n$apply$1.apply(RouteConcatenation.scala:32)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1$$anonfu
n$apply$1.apply(RouteConcatenation.scala:31)
sharedProjectJVM        at spray.routing.RequestContext$$anonfun$withRejectionHandling$1.applyOrElse(Req
uestContext.scala:130)
sharedProjectJVM        at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)

sharedProjectJVM        at spray.routing.RequestContext$$anon$1.handle(RequestContext.scala:84)
sharedProjectJVM        at akka.spray.UnregisteredActorRefBase.$bang(UnregisteredActorRefBase.scala:72)
sharedProjectJVM        at spray.routing.RequestContext.reject(RequestContext.scala:202)
sharedProjectJVM        at spray.routing.directives.RouteDirectives$$anon$1.apply(RouteDirectives.scala:
35)
sharedProjectJVM        at spray.routing.directives.RouteDirectives$$anon$1.apply(RouteDirectives.scala:
34)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anon$3$$anonfun$happly$1.apply(Basi
cDirectives.scala:92)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(R
outeConcatenation.scala:30)
sharedProjectJVM        at spray.routing.RouteConcatenation$RouteConcatenation$$anonfun$$tilde$1.apply(R
outeConcatenation.scala:29)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfu
n$apply$1.apply(BasicDirectives.scala:30)
sharedProjectJVM        at spray.routing.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$ano
nfun$apply$4.apply(ExecutionDirectives.scala:35)
sharedProjectJVM        at spray.routing.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$ano
nfun$apply$4.apply(ExecutionDirectives.scala:33)
sharedProjectJVM        at spray.routing.HttpServiceBase$class.runSealedRoute$1(HttpService.scala:36)
sharedProjectJVM        at spray.routing.HttpServiceBase$$anonfun$runRoute$1.applyOrElse(HttpService.sca
la:46)
sharedProjectJVM        at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
sharedProjectJVM        at spray.routing.SimpleRoutingApp$$anonfun$1$$anon$1.aroundReceive(SimpleRouting
App.scala:54)
sharedProjectJVM        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
sharedProjectJVM        at akka.actor.ActorCell.invoke(ActorCell.scala:487)
sharedProjectJVM        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254)
sharedProjectJVM        at akka.dispatch.Mailbox.run(Mailbox.scala:221)
sharedProjectJVM        at akka.dispatch.Mailbox.exec(Mailbox.scala:231)
sharedProjectJVM        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
sharedProjectJVM        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.
java:1253)
sharedProjectJVM        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:13
46)
sharedProjectJVM        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
sharedProjectJVM        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:
107)
sharedProjectJVM

now do this:

re-stop
clean
re-start

and it will work

lihaoyi commented 9 years ago

Cool, thanks =)

omidb commented 9 years ago

@lihaoyi thank you for all awesome libs

cvogt commented 9 years ago

re-start comes from the sbt-revolver plugin if I am not mistaken

ghost commented 9 years ago

I've been getting a similar error in my multi module sbt project too (the MatchError: Request). I don't have a stack trace right now.

Unfortunately I haven't got around to creating something to consistently reproduce the problem.

Things to note though is that it is possible to get into a state where I have to do a clean and full rebuild.

I've noticed that I can also fix the problem by adding a newline to a trait which contains my

def routes = route[MyApi](implementation)

Seems to trigger the macro to do its stuff. I don't know much about sbt but I found some scary looking stuff related to macros not really working with incremental compilation? https://groups.google.com/forum/#!topic/scala-user/GsFU0KddVaY

No idea if that is related to this though.

mlvn23 commented 8 years ago

Seems to be due to sbt/sbt#1729.

I can also reproduce this issue on scalajs-spa-tutorial's Play version by adding a new method (rename works) in the shared API and hitting refresh. My current work-around is to rename the Router every time I change the shared API (sbt clean also works, but that takes too long).

mlvn23 commented 8 years ago

I have a work-around in https://github.com/ochrons/scalajs-spa-tutorial/issues/25. It basically ensures that all router invocation gets recompiled when the Api trait changes by putting it in the same file as its implementation.

axos88 commented 5 years ago

I encountered this as well.