7

I'm trying to reprocude this or this, but I keep getting an error I am not able to fix...

First of all, here are my dependencies:

compile 'io.spray:spray-can_2.11:1.3.1'
compile 'io.spray:spray-routing_2.11:1.3.1',
compile 'io.spray:spray-json_2.11:1.2.6'

Now what I'm trying to do is:

class WHttpService extends Actor with HttpService with ActorLogging {

  implicit def actorRefFactory = context

  def receive = runRoute(route)

  lazy val route = logRequest(showReq _) {
    // Way too much imports but I tried all I could find
    import spray.json._
    import DefaultJsonProtocol._
    import MasterJsonProtocol._
    import spray.httpx.SprayJsonSupport._
    path("server" / Segment / DoubleNumber / DoubleNumber) { (login, first, second) =>
      get {
          complete {
            Answer(1, "test")
          }
      }
    }
  }

  private def showReq(req : HttpRequest) = LogEntry(req.uri, InfoLevel)
}

With:

case object MasterJsonProtocol extends DefaultJsonProtocol with SprayJsonSupport {
  import spray.json._

  case class Answer(code: Int, content: String)
  implicit val anwserFormat: JsonFormat[Answer] = jsonFormat2(Answer)
}

Now I get this error:

Error:(42, 19) type mismatch;
 found   : MasterJsonProtocol.Answer
 required: spray.httpx.marshalling.ToResponseMarshallable
            Answer(1, "test")
                  ^

I tried a lot of things but can't manage to make it works. I tried with

Answer(1, "test").toJson
Answer(1, "test").toJson.asJsObject

Finally what I did was

complete {
    Answer(1, "test").toJson.compactPrint
}

This works but it is sent to the client as Content-Type: text/plain when I need application/json.

Anyone see what the problem is here?

Edit: I added a sample project on github https://github.com/ydemartino/spray-test

Community
  • 1
  • 1
ydemartino
  • 242
  • 5
  • 10
  • +1. This is an awesome first post, welcome on SO :D – JoeBilly Jul 11 '14 at 19:27
  • I should have asked this in a top level comment. What version of Scala are you using? It looks like Spray doesn't have a release yet for 2.11 https://github.com/spray/spray/issues/790 – Gangstead Jul 11 '14 at 20:14
  • I saw this issue, but according to the official documentation: http://spray.io/project-info/current-versions/ "spray 1.3.1 is built against Scala 2.10.3 and Akka 2.3.0 as well as Scala 2.11.1 and Akka 2.3.2." As I could get the files using 'io.spray:spray-can_2.11:1.3.1' I thought they fixed it in the meantime. I will try with scala 2.10 to see if my code compile. – ydemartino Jul 11 '14 at 20:37
  • I added a sample project on github that allows to reproduce the problem. This project uses scala 2.10: https://github.com/ydemartino/spray-test – ydemartino Jul 11 '14 at 20:52

3 Answers3

4

Move your model outside of the json protocol and make it a regular object (not a case object)

case class Answer(code: Int, content: String)

object MasterJsonProtocol extends DefaultJsonProtocol {
  implicit val anwserFormat = jsonFormat2(Answer)
}

Edit

Also clean up your imports:

class WHttpService extends Actor with HttpService with ActorLogging {

  implicit def actorRefFactory = context

  def receive = runRoute(route)

  lazy val route = logRequest(showReq _) {
    // Way too much imports but I tried all I could find
    import MasterJsonProtocol._
    import spray.httpx.SprayJsonSupport._

    path("server" / Segment / DoubleNumber / DoubleNumber) { (login, first, second) =>
      get {
          complete {
            Answer(1, "test")
          }
      }
    }
  }

  private def showReq(req : HttpRequest) = LogEntry(req.uri, InfoLevel)
}
Gangstead
  • 4,152
  • 22
  • 35
  • Hey, thanks for the answer, I did what you said, turn it into an object (I actually did not notice it was a case object), removed the with SprayJsonSupport and moved the model outside but I am getting exactly the same error. – ydemartino Jul 11 '14 at 19:39
  • Hey, I tried with the imports cleaned up. Same thing. My IDE has the two of them greyed out as "Unused import statement", am I missing a dependency for this to work? – ydemartino Jul 11 '14 at 20:10
  • What version of Scala are you using? – Gangstead Jul 11 '14 at 20:12
  • Scala version 2.11.1 with jdk 1.8.05. I switch to jdk 1.7.60 to check if java was messing my build, but I got the same result. – ydemartino Jul 11 '14 at 20:29
2

I created a pull request to fix your problem: https://github.com/ydemartino/spray-test/pull/1

The json protocol object has to be declared before it can be used implicitly. I'm not wholly sure why the compiler can't figure it out, but moving the object declaration to the top fixed it.

For your actual project make sure to declare packages in each file then use those packages to in the import statements.

Gangstead
  • 4,152
  • 22
  • 35
  • Wow thanks! I cannot figure out why we have to declare it before either... Anyway there was a problem with the scala version, I tried the same code changing the dependencies to 2.11 and it won't compile with the error I had before... – ydemartino Jul 11 '14 at 21:20
0

In my case the name of the unresolvable implicit format instance conflicted with a local definition, so it got shadowed. The compiler was graciously silent about that. Only discovered that by accident after hours of head-banging.

Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169