有没有办法阻止 Scala 2.12 破坏 Jackson 对象映射器?

Posted

技术标签:

【中文标题】有没有办法阻止 Scala 2.12 破坏 Jackson 对象映射器?【英文标题】:Is there a way to stop Scala 2.12 breaking the Jackson object mapper? 【发布时间】:2021-09-01 16:56:02 【问题描述】:

我正在将我的 Scala 版本从 2.11 升级到 2.12,对象映射器似乎坏了。我的代码的其他部分需要仅在 2.12 下可用的功能。

using scala 2.12 with spark 2.1 提到重建杰克逊是一种可能的解决方案。这真的有必要还是有更简单的解决方案?

Scala 2.11.0 的 SBT 配置

// Identity
name := "ScalaJsonSpike00"
organization := "com.acme"

// Versions
version := "1.0"
scalaVersion := "2.11.0"

// Scala test
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.0" % "test"

// JSON
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.8.8"
// https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-scala_2.11
libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.8.8"

2.11 和 2.12 的代码

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

object Main 
  def main(args: Array[String]): Unit = 

    val originalMap = Map("a" -> List(1,2), "b" -> List(3,4,5), "c" -> List())
    val mapper = new ObjectMapper() with ScalaObjectMapper
    mapper.registerModule(DefaultScalaModule)
    println(mapper.writeValueAsString(originalMap))
  

Scala 2.11.0 的结果

"a":[1,2],"b":[3,4,5],"c":[]

SBT 配置更新到 scala 2.12.1

scalaVersion := "2.12.1"

Scala 2.12.1 的结果

com.intellij.rt.execution.application.AppMain Main
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper.$init$(Lcom/fasterxml/jackson/module/scala/experimental/ScalaObjectMapper;)V
    at Main$$anon$1.<init>(Main.scala:9)
    at Main$.main(Main.scala:9)
    at Main.main(Main.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

【问题讨论】:

我找不到任何关于在 使用 scala 2.12 和 spark 2.1 中重建 Jackson 的内容。你真的是想把这个特定的问题联系起来吗? 对不起,你是对的。我指的是这个评论'是的,但如果 scala 2.11 与 2.12 不兼容,它怎么能工作?并错误地将其应用于杰克逊。找了好久好累。 【参考方案1】:

您应该使用%% 来获取jackson-module-scala:适合您的Scala 版本:

libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.8"

在您当前的版本中,您始终使用此模块的 Scala 2.11 版本,它与 Scala 2.12 二进制不兼容。

Jackson 的核心库没有像 Java 那样的问题,因此不受 Scala 版本的任何影响。

【讨论】:

谢谢我将配置更新为以下libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.8",这对我的测试用例有用。 太棒了,拯救了我的一天! 有趣的更新:如果您试图让它在 Play 2.8.8 中工作,那么当前答案是:"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.12.3" 请参阅:***.com/questions/68009991/…【参考方案2】:

我发现可行的解决方案是将 ScalaObjectMapper 中的所有代码复制到扩展 Object Mapper 的 scala 类中,然后对其进行实例化。

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于有没有办法阻止 Scala 2.12 破坏 Jackson 对象映射器?的主要内容,如果未能解决你的问题,请参考以下文章

Android (5.0.1) Chrome 正在删除 javascript 空白和评论,有没有办法阻止这种情况?

热点Scala 2.12将只支持Java 8

com.typesafe.scala-logging#scala-logging-slf4j_2.12;2.1.2:未找到

如何使用 Scala 2.12 Zeppelin Notebook

未知工件 sbtplugin 带有 scala 2.12 的超级安全编译器

Scala 2.12 使用 Java 1.8;如果我们无法升级到 Java 1.8,我们该怎么办?