finagle-http 6.39.0 と jackson-databind 2.6系以外 (に依存するライブラリ)を共存させる

  • 1
    Like
  • 0
    Comment
More than 1 year has passed since last update.

finagle-http 6.38.0 と play-json 2.5.8 を使っているプロジェクトがあり、それぞれバージョンを最新に上げようとして、
何も変更せずテストコンパイルまで通ったので満足していたら、テストを実行したところ実行時例外が出た。

小さな再現例

build.sbt
scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.twitter" %% "finagle-http" % "6.39.0",
  "com.typesafe.play" %% "play-json" % "2.5.9"
)
$ sbt console
[info] Set current project to jackson-twitter (in build file:/Users/zaneli/ws/jackson-example/)
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions for evaluation. Or try :help.

scala> com.twitter.finagle.Http.client
com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.7.6
  at com.fasterxml.jackson.module.scala.JacksonModule$class.setupModule(JacksonModule.scala:64)
  at com.fasterxml.jackson.module.scala.DefaultScalaModule.setupModule(DefaultScalaModule.scala:19)
  at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:730)
  at com.twitter.finagle.toggle.JsonToggleMap$.<init>(JsonToggleMap.scala:79)
  at com.twitter.finagle.toggle.JsonToggleMap$.<clinit>(JsonToggleMap.scala)
  at com.twitter.finagle.toggle.StandardToggleMap$.loadJsonConfigWithEnv(StandardToggleMap.scala:183)
  at com.twitter.finagle.toggle.StandardToggleMap$.loadJsonConfig(StandardToggleMap.scala:123)
  at com.twitter.finagle.toggle.StandardToggleMap$.apply(StandardToggleMap.scala:99)
  at com.twitter.finagle.toggle.StandardToggleMap$.apply(StandardToggleMap.scala:80)
  at com.twitter.finagle.http.package$.<init>(package.scala:18)
  at com.twitter.finagle.http.package$.<clinit>(package.scala)
  at com.twitter.finagle.Http$.<init>(Http.scala:142)
  at com.twitter.finagle.Http$.<clinit>(Http.scala)
  ... 42 elided

JacksonModule.setupModule()でsetupする側とされる側?とのメジャーバージョン・マイナーバージョンの一致をチェックしているようだ。

finagle-http 6.38.0 で起きていなかったのはバージョンが一致していたわけではなく、
finagle-toggle に依存しておらずそもそもこのコードが実行されていないためと思われる。

とりあえず無理に finagle-http のバージョンを上げない事にしたが、どうしても 6.39.0 に上げたい場合、どうすればいいだろう。

exclude() で play-json 側の jackson-databind を依存から除く

build.sbt
scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.twitter" %% "finagle-http" % "6.39.0",
  "com.typesafe.play" %% "play-json" % "2.5.9" exclude("com.fasterxml.jackson.core", "jackson-databind")
)

force() でバージョンを固定する

build.sbt
scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.twitter" %% "finagle-http" % "6.39.0",
  "com.typesafe.play" %% "play-json" % "2.5.9",
  "com.fasterxml.jackson.core" % "jackson-core" % "2.6.5" force(),
  "com.fasterxml.jackson.core" % "jackson-annotations" % "2.6.5" force(),
  "com.fasterxml.jackson.core" % "jackson-databind" % "2.6.5" force()
)

jackson-databind だけでいいかと思ったけど、更に依存する core と annotations も追加しないといけなかった。
この辺はsbt-dependency-graphを見ながら試してみた結果。

しかし本当に除外しちゃっていいんだろうか…逆に play-json 側で jackson 2.7.6 が必要な箇所があったりして実行時例外が出そうな気も…。

finagle-http 次バージョンを待つ

現在の finagle develop ブランチでは jacksonVersion が 2.8.3 になっている。
という事は次(6.40.0?)のリリースを待つのが最も安全かな?
しかしマイナーバージョンが2つあがるとそれはそれで問題になりそうな気もする…。