Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extraction fails with Scala 3 ("Can't find ScalaSig") #1035

Open
charpov opened this issue Mar 24, 2022 · 9 comments · May be fixed by #1460
Open

Extraction fails with Scala 3 ("Can't find ScalaSig") #1035

charpov opened this issue Mar 24, 2022 · 9 comments · May be fixed by #1460

Comments

@charpov
Copy link

charpov commented Mar 24, 2022

json4s version

val Json4sNative = "org.json4s" %% "json4s-native" % "4.0.4"

scala version

scalaVersion := "3.1.1"

jdk version

Java 17.0.2

failure

A type is defined as a case class:

package ecn

case class OrderRecord(
    stock: String,
    shares: Int,
    price: Option[Int],
    duration: Option[Double]
)

This simple test fails:

package ecn

import org.json4s.native.JsonParser
import org.json4s.DefaultFormats
import org.json4s.jvalue2extractable

object Json {

   implicit val formats: DefaultFormats = DefaultFormats

   def main(args: Array[String]): Unit =
      val json = JsonParser.parse("""{"stock":"C","shares":100}""")
      println(json.extract[OrderRecord])
}

with an error:

Exception in thread "main" org.json4s.MappingException: Can't find ScalaSig for class ecn.OrderRecord
	at org.json4s.reflect.package$.fail(package.scala:56)
	at org.json4s.reflect.ScalaSigReader$.$anonfun$7(ScalaSigReader.scala:81)
	at scala.Option.getOrElse(Option.scala:201)
        ...
@jarikujansuu
Copy link

My issue is probably related. I can't serialize any case class if it contains any List, Option or anything. Also fail with same ScalaSig error

So following works

import org.json4s._
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.{read, write}

case class A(value: Int)
case class B(value: Option[Int])
case class C(value: List[Int])

implicit val formats: Formats = DefaultFormats

write(A(1)) // works
write(List(A(1), A(2))) // works

write(Option(1)) // works
write(B(Option(1))) // doesn't

write(List(1,2)) // works
write(C(List(1,2)))  // doesn't

From the documentation I get impression that these simple case classes should work automatically without creating custom serializers for everything that has any Option, List etc.

@TomLous
Copy link

TomLous commented Aug 15, 2022

I found this issue after figuring out I had a similar error:
https://gitter.im/json4s/json4s?at=62f6032711a6a83d04ef6edc

Any update on a work around or fix?
I wish I could help, but have no idea where to start.

@charpov
Copy link
Author

charpov commented Aug 15, 2022

I ended up switching my project to Jackson (https://github.com/FasterXML/jackson-module-scala). I still ran into a problem, which may be related to yours: I had to replace Option[Int] with Option[Integer] and Option[Double] with Option[java.lang.Double]. The Scala compiler uses a bunch of tricks to handle "primitive" types inside generic containers, and the assignments (through reflection) used during deserialization ran afoul of them.

@plokhotnyuk
Copy link
Contributor

Yet another workaround is using jsoniter-scala. It is safer and much efficient in the runtime with support of Option and all Scala collection types out of the box.

Only difference that for each top-level type of message you will need to derive a codec explicitly. It can be done using derives (in Scala 3) like here. For cases when source of message definitions cannot be changed given definitions can be used like here.

@gregghz
Copy link

gregghz commented Jan 10, 2023

This bug is nearly a year old and I think completely breaks json4s in scala 3 (at least it does for my use case). Are there any plans to address this?

@gregghz
Copy link

gregghz commented Jan 25, 2023

fwiw, it looks like the byte code representation of scala 3 removed the "ScalaSignature" annotation which is required by json4s here https://github.com/json4s/json4s/blob/master/scalap/src/main/scala/org/json4s/scalap/scalasig/ScalaSig.scala#L43

I'm not really sure what this is used for or how to acquire this info otherwise. At a glance (though I'm far from an expert) the byte code looks roughly the same otherwise.

@gregghz
Copy link

gregghz commented May 11, 2023

This is still present in scala 3.2.2 and json4s 4.0.6 (and 4.1.0-M3).

@gregghz
Copy link

gregghz commented May 25, 2023

This is still present in json4s 4.0.6 and 4.1.0-M3 with scala 3.3.0.

@martin-ockajak
Copy link

martin-ockajak commented Feb 13, 2024

The error still occurs in versions 4.0.7 and 4.1.0-M4. Minimal example to reproduce:

#!/usr/bin/env -S scala-cli -q
//> using scala 3.3.1
//> using dep org.json4s::json4s-native:4.0.7

import org.json4s.{Extraction, DefaultFormats, Formats}

case class Test(value: Option[Int])

implicit val formats: Formats = DefaultFormats

Extraction.decompose(Test(Some(0)))

Output:

Exception in thread "main" org.json4s.MappingException: Can't find ScalaSig for class case$minusclass$minusoption$minuserror$_$Test

jnatten added a commit to NDLANO/backend that referenced this issue Mar 13, 2024
This patch removes `json4s` from `common` and `network`.

Json4s doesn't seem to work with scala 3. Since we're already fairly
invested in circe lets remove that.

See: json4s/json4s#1035
jnatten added a commit to NDLANO/backend that referenced this issue Mar 13, 2024
This patch removes `json4s` from `common` and `network`.

Json4s doesn't seem to work with scala 3. Since we're already fairly
invested in circe lets remove that.

See: json4s/json4s#1035
jnatten added a commit to NDLANO/backend that referenced this issue Mar 14, 2024
This patch removes `json4s` from `common` and `network`.

Json4s doesn't seem to work with scala 3. Since we're already fairly
invested in circe lets remove that.

See: json4s/json4s#1035
jnatten added a commit to NDLANO/backend that referenced this issue Mar 15, 2024
This patch removes `json4s` from `common` and `network`.

Json4s doesn't seem to work with scala 3. Since we're already fairly
invested in circe lets remove that.

See: json4s/json4s#1035
jnatten added a commit to NDLANO/backend that referenced this issue Mar 19, 2024
This patch removes `json4s` from `common` and `network`.

Json4s doesn't seem to work with scala 3. Since we're already fairly
invested in circe lets remove that.

See: json4s/json4s#1035
@jchyb jchyb linked a pull request Apr 28, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

6 participants