Spray-json: [error] Referring to non-existent class spray.json.package$ - scala

I am following this. I have defined JsonFormat for my custom case class as:
object RecipeJsonProtocol extends DefaultJsonProtocol {
implicit val recipeFormat = jsonFormat4(Recipe.apply)
}
...and then used it as following in same file:
import RecipeJsonProtocol._
def postRecipe(recipe: Recipe): Callback = {
val json = recipe.toJson.toString()
Ajax.post(url = "....", data = json).onComplete {
case Success(xhr) => println("....")
case Failure(t) => println("An error has occurred: " + t.getMessage)
}
Callback.empty
}
But this is throwing error as:
[error] Referring to non-existent class spray.json.package$
What's wrong here?

Related

Scala runtime compilation: how to get line number of the error message?

I have found that scala compiler report compile error differently depends on whether it is used in compile-time or run-time.
E.g. for a simple implicit not found case, in compile time the report is:
newSource1.scala:6: error: type mismatch;
L|R
f(new L)
^
In runtime, when the same code was evaluated and the error message was captured directly:
class TestCase(code: String, extra: String) {
def toolbox(extra: String): ToolBox[universe.type] = {
ToolBox(cm).mkToolBox(options = s"$opts $extra")
}
def compile(): Any = {
import SpecHelpers._
val tb = toolbox(extra)
tb.eval(tb.parse(code))
}
def compileError(): String =
Try(compile()) match {
case Failure(ee) =>
ee match {
case te: ToolBoxError =>
te.message.linesIterator.toList.drop(2).mkString("\n")
case t =>
throw t
}
case Success(_) =>
sys.error("compiling succeeded")
}
}
the line number and location cursor is omitted:;
implicit error;
!I e: F[Arg]
Is there a way to add the missing part back?
You can specify frontEnd for ToolBox (default frontEnd is mkSilentFrontEnd())
val tb = cm.mkToolBox(
frontEnd = new FrontEnd {
override def display(info: Info): Unit = println(info)
},
options = "-Xlog-implicits -Vimplicits -Vimplicits-verbose-tree -d out"
// with `-d out` toolbox keeps `.class` files in directory `out`
// rather than in memory, so you can decompile `.class` files
// if you want to investigate auto-generated code
)
tb.compile(tb.parse(
"""implicit val i: Int = 1
|implicitly[String]""".stripMargin))
//Info(source-<toolbox>,line-2,offset=34,implicit error;
//!I e: String,ERROR)
//Exception in thread "main" java.lang.ExceptionInInitializerError
// at App.main(App.scala)
//Caused by: scala.tools.reflect.ToolBoxError: reflective compilation has failed:
//
//implicit error;
//!I e: String
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:332)
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.wrapInPackageAndCompile(ToolBoxFactory.scala:214)
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:268)
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.$anonfun$compile$13(ToolBoxFactory.scala:445)
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:371)
// at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:438)
// at App$.<clinit>(App.scala:20)
// ... 1 more

How can I serialize Sangria responses with json4s and Akka HTTP?

I'm working through a slight variation of Sangria's Getting Started, using Akka HTTP. I'm attempting to use json4s-jackson as the serializaltion lib, but am running in to some trouble getting the response I want.
Specifically, the serialized response I get is the JSON version of the (StatusCode, Node) tuple:
{
"_1": {
"allowsEntity": true,
"defaultMessage": "OK",
"intValue": 200,
"reason": "OK"
},
"_2": {
"data": {
"foo": {
"id": "1",
"name": "Foo"
}
}
}
}
The data portion is correct, but obviously I just want that and not the first element of the serialized tuple.
I'm using akka-http-json4s, so my trait with route looks like:
case class GraphQlData(query: String, operation: Option[String])
trait FooController {
import de.heikoseeberger.akkahttpjson4s.Json4sSupport._
implicit val serialization = jackson.Serialization
implicit val formats = DefaultFormats
val fooRoutes = post {
entity(as[GraphQlData]) { data =>
QueryParser.parse(data.query) match {
// query parsed successfully, time to execute it!
case Success(queryAst) =>
complete {
Executor
.execute(
SchemaDefinition.FooSchema,
queryAst,
new FooService,
operationName = data.operation
)
.map(OK -> _)
.recover {
case error: QueryAnalysisError => BadRequest -> error.resolveError
case error: ErrorWithResolver => InternalServerError -> error.resolveError
}
}
// can't parse GraphQL query, return error
case Failure(error) =>
complete(BadRequest -> error.getMessage)
}
}
}
implicit def executionContext: ExecutionContext
}
For the life of me I can't figure out what's wrong. I've been looking at sangria-akka-http-example but it seems to be exactly the same, with the exception of using spray-json instead of json4s.
Ideas? Thanks!
Ah, figured it out. I neglected to add
import sangria.marshalling.json4s.jackson._
to the trait defining the route. Adding it does the trick.
Just wanted to provide a quick update to this answer for the full GraphQLRequest. Now the variables are included in the request.
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import org.json4s._
import org.json4s.JsonAST.JObject
import sangria.marshalling.json4s.jackson._
case class GQLRequest(query: String, operationName: Option[String], variables: JObject)
trait SomeJsonSupport extends Json4sSupport {
implicit val serialization = jackson.Serialization
implicit val formats = DefaultFormats
}
trait GraphQLResource extends SomeJsonSupport{
implicit val timeout:Timeout
implicit val system:ActorSystem
import system.dispatcher
def graphqlRoute: Route =
(post & path("graphql")) {
entity(as[GQLRequest]) { requestJson =>
println(s"This is the requestJson = $requestJson")
graphQLEndpoint(requestJson)
}
} ~
get {
println(s"This is working")
getFromResource("graphiql.html")
}
def graphQLEndpoint(requestJson: GQLRequest): Route = {
val route = QueryParser.parse(requestJson.query) match {
case Success(query) =>
println(s"This is the query $query")
val vars = requestJson.variables match {
case jObj:JObject => jObj
case _ => JObject(List.empty)
}
val futureJValue = Executor.execute(clientSchema,
query,
NclhGqlRequest(this),
operationName = requestJson.operationName,
variables = vars)
val futureTupleStatusCodeJValue = futureJValue.map(OK -> _).recover {
case error: QueryAnalysisError => BadRequest -> error.resolveError
case error: ErrorWithResolver => InternalServerError -> error.resolveError
}
complete(futureTupleStatusCodeJValue)
case Failure(error) =>
complete(BadRequest, error.getMessage)
}
route
}

Mockito with Dependency Injection

I'm using Play Framework 2.5 and trying to test one of my DAO class based on the example here.
But my class under test has dependency injection and I wonder how to mock it.
I tried to do something but it seems a bit clumsy, and I would like help to improve it.
Here is my code :
class MyController #Inject()(val mydao: MyDAOClass) extends Controller {
def getData = Action { request =>
mydao.fetchData
}
}
class MyDAOClass #Inject()(ws: WSClient) {
def urls(): List[String] = { List("url1", "url2") }
// fetch data on different servers and should merge it.
def fetchData(): Future[List[String]] = {
val futures: List[Future[WSResponse]] = urls map { url =>
ws.url(url + "/some/data").withRequestTimeout(10000.millis).get()
}
futures map { future =>
future onComplete {
case Success(resp) => println(resp.json)
case Failure(t) => println("An error has occured: " + t.printStackTrace)
}
}
Future(List())
}
}
Here is my test code :
trait DAOTrait {
def urls: List[String]
}
class MyDAOClass extends PlaySpec with MockitoSugar {
"MyDAOClass" should {
"get a list of data" in {
Server.withRouter() {
case GET(p"/url1/some/data") => Action {
Results.Ok(Json.arr(Json.obj("name" -> "data1")))
}
} { implicit port =>
val mockMyDAOClass = mock[DAOTrait]
when(mockMyDAOClass.urls) thenReturn List("url1")
implicit val materializer = Play.current.materializer
WsTestClient.withClient { client =>
val mydao = new MyDAOClass(client) {
override def urls = mockMyDAOClass.urls
}
val result = Await.result(
mydao.fetchData(), 10.seconds)
result mustEqual List("data1")
}
}
}
}
}
The code is not finished in MyDAOClass, but it is enough to start implementing tests.
1) How to mock class that have dependency injection ?
2) When testing this code I have the following exception in MyDAOClass case Failure(t)
java.net.ConnectException: http://localhost:40183
at org.asynchttpclient.netty.channel.NettyConnectListener.onFailure(NettyConnectListener.java:137)
at org.asynchttpclient.netty.request.NettyChannelConnector$1.onFailure(NettyChannelConnector.java:106)
at org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:28)
at org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:20)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:683)
at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:604)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:564)
at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:425)
at io.netty.channel.nio.AbstractNioChannel.doClose(AbstractNioChannel.java:462)
at io.netty.channel.socket.nio.NioSocketChannel.doClose(NioSocketChannel.java:236)
at io.netty.channel.AbstractChannel$AbstractUnsafe.doClose0(AbstractChannel.java:611)
at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:590)
at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:534)
at io.netty.channel.nio.NioEventLoop.closeAll(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:361)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.channels.ClosedChannelException
but it should return Result.Ok instead.
3) Any advice welcome.

Scala: Partial function error: use _ if you want to treat it as a PartialFunction

The following piece of code does not work:
FileSystems.getDefault.getPath is from the java.nio package
Update:
Method createCalculation is:
Note: MyLocation is a case class that extends MyMessage
def creatCalculation(myPlace: MyLocation): MyMessage = {
if (some test) {
//--- some code
} else
MyError("My Calculation already done")
MyAck //returning the case object MyAck which is of type MyMessage
}
//Req is the class from: net.liftweb.http.Req
val someVal: PartialFunction[Req, () => Box[LiftResponse]] {
case "create" :: Nil JsonPostAndApproval s =>
postResponse(s, (j: JValue, p: Permissions, r: Req) => {
createCalculation(fromJValue[MyLocation](j) = {
case "MyAck" => {
val myCalculator: Calculator = new Calculator(FileSystems.getDefault.getPath(fromJsonVal[MyLocation](s._1).path))
val resultsMap = myCalculator.foreach( (p) => Map[String, Int])
for( (myKey, myValue) <- resultsMap) {
printf("key: %s, value: %s\n", myKey, myValue)
}
}
})
} ) ("Failed to calculate")
}
The compiler complains like this:
[error] C:\Users\lulu\ExampleHandler.scala:129: missing arguments for
method fromJValue in package json;
[error] follow this method with `_' if you want to treat it as a partially applied function
[error] createCalculation(fromJsonVal[MyLocation](j) = {
[error] ^
This is the method definition for fromJsonVal
/**
* Routine to convert JValue to native type
*
* #param in JValue to convert
* #tparam T native type to extract
* #return extracted native type
*/
def fromJsonVal[T: Manifest](in: JValue): T = in.extract[T]
JValue is from net.liftweb/json and is:
sealed abstract class JValue()extends java.lang.Object with net.liftweb.json.Diff.Diffable {
<>
}
Update: the compiler is reporting an error is in this line of code
How do you think I should correct this compile error?
createCalculation(fromJValue[MyLocation](j) = {
Without the full picture, I think the error is merely from you trying to assign an output to a method AND a missing parens. Without the full picture, my guess would be that you are looking for something more like:
createCalculation(fromJValue[MyLocation](j)) match {
case "MyAck"....
Note the double paren after j

"scala is not an enclosing class"

When compiling this specification:
import org.specs.Specification
import org.specs.matcher.extension.ParserMatchers
class ParserSpec extends Specification with ParserMatchers {
type Elem = Char
"Vaadin DSL parser" should {
"parse attributes in parentheses" in {
DslParser.attributes must(
succeedOn(stringReader("""(attr1="val1")""")).
withResult(Map[String, AttrVal]("attr1" -> AttrVal("val1", "String"))))
}
}
}
I get the following error:
ParserSpec.scala:21
error: scala is not an enclosing class
withResult(Map[String, AttrVal]("attr1" -> AttrVal("val1", "String"))))
^
I don't understand the error message here at all. Why could it appear?
Scala version is 2.8.1, specs version is 1.6.7.2.
DslParser.attributes has type Parser[Map[String, AttrVal]] and the combinators succeedOn and withResult are defined as follows:
trait ParserMatchers extends Parsers with Matchers {
case class SucceedOn[T](str: Input,
resultMatcherOpt: Option[Matcher[T]]) extends Matcher[Parser[T]] {
def apply(parserBN: => Parser[T]) = {
val parser = parserBN
val parseResult = parser(str)
parseResult match {
case Success(result, remainingInput) =>
val succParseMsg = "Parser "+parser+" succeeded on input "+str+" with result "+result
val okMsgBuffer = new StringBuilder(succParseMsg)
val koMsgBuffer = new StringBuilder(succParseMsg)
val cond = resultMatcherOpt match {
case None =>
true
case Some(resultMatcher) =>
resultMatcher(result) match {
case (success, okMessage, koMessage) =>
okMsgBuffer.append(" and ").append(okMessage)
koMsgBuffer.append(" but ").append(koMessage)
success
}
}
(cond, okMsgBuffer.toString, koMsgBuffer.toString)
case _ =>
(false, "Parser succeeded", "Parser "+parser+": "+parseResult)
}
}
def resultMust(resultMatcher: Matcher[T]) = this.copy(resultMatcherOpt = Some(resultMatcher))
def withResult(expectedResult: T) = resultMust(beEqualTo(expectedResult))
def ignoringResult = this.copy(resultMatcherOpt = None)
}
def succeedOn[T](str: Input, expectedResultOpt: Option[Matcher[T]] = None) =
SucceedOn(str, expectedResultOpt)
implicit def stringReader(str: String): Reader[Char] = new CharSequenceReader(str)
}
This message can occur while the compiler is really trying to signal a type error or a type inference failure. It's a bug (or family of bugs) in scalac.
To locate the problem, progressively add in explicit types and type arguments; break complex expressions into smaller subexpressions.
For bonus points, produce a standalone example and file a bug.