Error [package com.fasterxml.jackson.databind does not exist]

package com.fasterxml.jackson.databind does not exist の直し方(Spring Boot 4 / Jackson 3 の部分改名)

FIX SUMMARY verified
Applies when
maven@sha256:2b4496088e7b80ae10a8c9f74e574ea21380325a006ec684532ad6bad5bc7273spring-boot-starter-json (Spring Boot 4 ships Jackson 3: databind/core renamed to tools.jackson, while jackson-annotations stays at com.fasterxml 2.20)upgrading Spring Boot 3.x to 4.0.0 with imports still on com.fasterxml.jackson.databind — annotations imports keep compiling on the same classpath, so only databind/core call sites fail

Verified: reproduced in maven@sha256:2b4496088e7b80ae10a8c9f74e574ea21380325a006ec684532ad6bad5bc7273, then the package com.fasterxml.jackson.databind does not exist signature was gone after the fix (exit 0).

Spring Boot を 3 系から 4 に上げた直後のビルドが、次のコンパイルエラーで止まります。

Main.java:1: error: package com.fasterxml.jackson.databind does not exist
import com.fasterxml.jackson.databind.ObjectMapper;
                                     ^
Main.java:5: error: cannot find symbol
    ObjectMapper mapper = new ObjectMapper();
    ^
  symbol:   class ObjectMapper
  location: class Main

依存の宣言も import も Boot 3 のときのままで、このエラーだけが新しく出ます。Boot 4 が管理する Jackson 3 は、 Maven 座標と Java package の両方を com.fasterxml.jackson から tools.jackson へ改名しています—— ただし全部ではありません。annotations だけが旧名に残るため、同じソースの import が一部だけ通ります。

直し方の要点を先に

databind の import を tools.jackson へ書き換えます。com.fasterxml.jackson.annotation の import はそのまま残します。

import com.fasterxml.jackson.annotation.JsonProperty;   // 変えない(Jackson 3 でもこの package のまま)
import tools.jackson.databind.ObjectMapper;             // 旧: com.fasterxml.jackson.databind.ObjectMapper

public class Employee {
  @JsonProperty("employee_id")
  public int id;
}

引数なしの new ObjectMapper() は Jackson 3 でも動きます(3.0.2 でコンパイル・実行とも実測済み)。ただし Jackson 3 の ObjectMapper は生成後に設定を変えられません——configure(...)setSerializationInclusion(...) などの設定メソッドは 3.0 で削除されており、呼んでいる行は cannot find symbol でコンパイルが止まります。 設定を持つ mapper は JsonMapper.builder()....build() で組みます(上流の移行ガイドの推奨もこちら。 組み方の実例は姉妹記事にあります)。依存の追加は不要です——spring-boot-starter-json が Jackson 3 の databind を運んでいます(検証もこの starter だけの構成で行いました)。

なぜ Spring Boot 4 で出るのか:Jackson 3 の改名は annotations を除く部分改名

Spring Boot 4.0.0 の spring-boot-starter-json が classpath に置く Jackson は、mvn dependency:tree の実測でこうなっています。

モジュールBoot 3.4.1(Jackson 2・実測)Boot 4.0.0(Jackson 3・実測)
databindcom.fasterxml.jackson.core:jackson-databind(2.18.2)tools.jackson.core:jackson-databind(3.0.2)
corecom.fasterxml.jackson.core:jackson-coretools.jackson.core:jackson-core(3.0.2)
annotationscom.fasterxml.jackson.core:jackson-annotationscom.fasterxml.jackson.core:jackson-annotations座標・package とも旧名のまま。版は 2.20)

(版番号は実測した2点のもの。Boot 3 系でも databind の座標と package は同じですが、管理される版は Boot の版ごとに違います。)

classpath に com.fasterxml.jackson.databind package を提供する jar が居なくなったので、旧 import のコンパイルが does not exist で止まります。一方 annotations は座標も package も変わらず classpath に残るので、同じ Boot 4.0.0 の classpath で次の2つが同時に成り立ちます(どちらも実測)。

  • import com.fasterxml.jackson.databind.ObjectMapper;コンパイルエラー
  • import com.fasterxml.jackson.annotation.JsonProperty;コンパイル成功

@JsonProperty@JsonIgnore の import が通り続けるため、エラーになるのは databind/core を直接触る箇所だけです。 annotations を旧名に残すのは Jackson 3 の設計判断です——2 系と 3 系のどちらからも同じ annotation を読めるように する互換措置で、移行中にドメインクラスの annotation を付け替えずに済みます(Jackson の移行ガイドが明記しています)。

書き換えの判断基準は Java annotation かどうかではなく、module 単位で決まります:旧名に残るのは jackson-annotations module(com.fasterxml.jackson.annotation.*)だけです。同じ annotation でも databind に属する @JsonSerialize / @JsonDeserializecom.fasterxml.jackson.databind.annotation.*)は tools.jackson.databind.annotation.* へ動きます(旧 import はコンパイルエラー・新 import は成功、を実測)。

旧 Jackson 2 を classpath に足すとどうなるか

依存に com.fasterxml.jackson.core:jackson-databind:2.18.2 を明示追加する経路も実測しました。旧 import のままの コードがコンパイル・実行とも通ります(classpath には jackson-databind-3.0.2.jarjackson-databind-2.18.2.jar が 両方載り、tools.jacksoncom.fasterxml.jackson は別 package なので FQCN は衝突しません)。なお明示追加した databind は 2.18.2 でも、Jackson 2 側の core と annotations は Boot 4 の依存管理が 2.20 系(2.20.1/2.20)を 選びます——Jackson 2 側の内部でも版がズレて組まれる、ということです。

実測が示すのはそこまでです。この構成はアプリの中で Jackson 2 と Jackson 3 の2世代が並走することを意味し、 自分のコードがどちらの ObjectMapper を使うかと、Boot 4 側の JSON 変換(既定は Jackson 3。Jackson 2 の 自動構成も非推奨のまま同梱されています)がどちらを使うかは別々に決まります。単純なプローブが通ることは、 混在した実アプリ全体の互換を示しません。Boot 4 での段階移行には公式の経路もあります——spring-boot-jackson2 モジュールと spring.jackson2.* 設定が、非推奨(将来削除予定)の一時経路として Boot 4.0 のリリースノートに 明記されています。どの経路を取るにせよ、進む先は import の書き換えです。

切り分け(うまくいかないとき)

  • コンパイルは通ったのに、実行時に Cannot map nullinto typeint“ が出るようになった:Jackson 3 は 名前空間だけでなく既定の挙動も変えています(JSON の null をプリミティブに入れる変換が既定で例外に)。 Cannot map null into type int の直し方 を参照してください。
  • エラーが package javax.persistence does not exist など javax.* 系で出ている:それは Boot 4 ではなく Boot 2→3(Jakarta EE 9 の名前空間改名)の境界です。形は同じ「版を上げたら package が消える」ですが、 改名したコンポーネントが違います。 package javax.persistence does not exist の直し方 を参照してください。
  • jakarta.mail のように、依存の版だけで package が変わった経験がある:あちらは「座標が先に改名され、 中身が後から追いつく」罠でした。Jackson 3 は逆に「座標と package は同時に変わるが、annotations という module だけが旧名に残る」形です。どちらも改名が一斉でないことが引っかかりの原因ですが、確認する軸が 違います(あちらは版、こちらは module)。 package javax.mail does not exist の直し方 を参照してください。
  • 自分のコードは直したのに、依存ライブラリの中で com.fasterxml.jackson.databind 系の NoClassDefFoundError が 実行時に出る:そのライブラリが Jackson 2 の databind を前提にしています。ライブラリ側の Jackson 3 対応版を 探すか、上の「旧 Jackson 2 を classpath に足す」の限定を踏まえて2世代並走を検討することになります。

検証環境

  • maven:3.9-eclipse-temurin-21(digest 固定)の中で Maven を実行(依存の取得にのみネットワークを使用)
  • 依存は spring-boot-starter-json のみ(Spring MVC もサーバも使わない最小構成)
  • 再現:Spring Boot 4.0.0 の classpath で import com.fasterxml.jackson.databind.ObjectMapper; をコンパイルすると package com.fasterxml.jackson.databind does not exist で終了コード 1
  • 修正:databind の import を tools.jackson.databind.ObjectMapper に書き換え(@JsonProperty の import は com.fasterxml.jackson.annotation のまま)、コンパイル・実行とも終了コード 0・シグネチャ消滅

再現から修正までは errfix の検証ハーネスが機械的に確認しています。「annotations の import は同じ classpath で通る」 「new ObjectMapper() が Jackson 3.0.2 で動く」「旧 Jackson 2 databind の明示追加で旧 import が動く」の3点は 個別に実測しました(各結果はケースの verification/probes.txt に記録)。座標と版の対応は mvn dependency:tree で 確認しています。

検証(machine-verified)

この修正は maven@sha256:2b4496088e7b80ae10a8c9f74e574ea21380325a006ec684532ad6bad5bc7273 のバージョン固定コンテナ内で再現し、修正後に package com.fasterxml.jackson.databind does not exist のシグネチャが消えることを機械で確認しています。

verify — run-case.mjs
$ node run-case.mjs jvm/jackson3-namespace-migration
● reproduce package com.fasterxml.jackson.databind does not exist present ✓
● apply fix exit 0
● re-run package com.fasterxml.jackson.databind does not exist gone ✓
PASS verified · maven@sha256:2b4496088e7b80ae10a8c9f74e574ea21380325a006ec684532ad6bad5bc7273 · signature gone

確認したのは上のイメージの中だけです。別の環境で直らなかった、記述が違う、という場合は 報告してください(対象と検証イメージは件名・本文に入ります)。