33

I have following Scala console session for json4s, where I am trying to extract String value from a parsed json:

scala> import org.json4s._
import org.json4s._

scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._

scala> val s = """ {"a": "hello"} """
s: String = " {"a": "hello"} "

scala> val json = parse(s)
json: org.json4s.JValue = JObject(List((a,JString(hello))))

scala> json \ "a"
res0: org.json4s.JValue = JString(hello)

scala> res0.extract[String]
<console>:17: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

scala> import org.json4s.Formats._
import org.json4s.Formats._

scala> res0.extract[String]
<console>:20: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

scala> import org.json4s.DefaultFormats._
import org.json4s.DefaultFormats._

scala> res0.extract[String]
<console>:23: error: No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
              res0.extract[String]
                          ^

org.json4s.DefaultFormats, org.json4s.Formats and there members are already in scope. How can I fix this?

EDIT1

From @mfirry 's answer, this works:

scala> implicit val formats = DefaultFormats
formats: org.json4s.DefaultFormats.type = org.json4s.DefaultFormats$@12b195f5

scala> val json = parse(""" {"a": "hello", "b": 1.2} """)
json: org.json4s.JValue = JObject(List((a,JString(hello)), (b,JDouble(1.2))))

scala> (json \ "b").extract[String]
res6: String = 1.2

scala> (json \ "b").extract[Double]
res7: Double = 1.2
Community
  • 1
  • 1
tuxdna
  • 8,257
  • 4
  • 43
  • 61

1 Answers1

72

You just need to add

implicit val formats = DefaultFormats

and it'll work just ok.

mfirry
  • 3,634
  • 1
  • 26
  • 36
  • 17
    why this is required?? – Nilesh Oct 12 '16 at 06:03
  • And if you need this in a class, you can just declare it at the top of the class – cph2117 Aug 04 '17 at 15:26
  • Even if you just need it in a function, declare it at the top better than above. It will prevent for further java.io.NotSerializableException – ivankeller Oct 06 '17 at 13:47
  • I second @Nilesh. What makes this work and why is it necessary? – starscream_disco_party Nov 29 '17 at 14:55
  • 1
    So a few methods from json4s api (namely `render`) require an implicit `Formats` parameter. Formats contain stuff like date formatting rules and other settings. So Json4s gives you a default you can use. By adding that line you'll have it in scope. Have look for more details: https://github.com/json4s/json4s/blob/3.6/core/src/main/scala/org/json4s/Formats.scala#L331 – mfirry Dec 01 '17 at 05:57
  • @mfirry How do we know for the methods that they need something to be imported implicitly. Can you please point out some syntactic hint? – SrinR May 15 '18 at 16:44
  • For example If you look at json4s source code you'll see ` def extract[A](implicit formats: Formats, mf: scala.reflect.Manifest[A]): A = ` – mfirry May 16 '18 at 06:06