Migrate a Java project from Jackson 2 to Jackson 3. Use this skill whenever the user wants to upgrade Jackson, mentions jackson-databind, com.fasterxml.jackson imports, or asks about moving from Jackson 2.x to 3.x. Also trigger when the user shares Java/Kotlin code or build files (pom.xml, build.gradle) containing Jackson 2 dependencies and asks to update, modernize, or migrate them. This skill covers import renaming, dependency GroupId changes, API migrations, IOException-to-JacksonException changes, ObjectMapper builder patterns, BOM usage in multi-module Maven projects, and OpenRewrite recipe usage.
Jackson 3 is a major version with breaking changes. The key ones are:
com.fasterxml.jackson → tools.jacksonthrows IOException now declare throws JacksonExceptionObjectMapper builder pattern is now strongly preferredBefore doing anything, read the full reference:
→ references/jackson2-to-3-changes.md
Choose the right approach based on what the user has:
| User provides | Approach |
|---|---|
pom.xml / build.gradle only | Update dependencies, add BOM, explain code changes needed |
| Java/Kotlin source files |
| Migrate imports + update API usage + fix exception handling |
| Both build + source | Do both |
| Asking how to automate | Recommend OpenRewrite recipe |
Scan the project for:
com.fasterxml.jackson.* groupIds in POM filesimport com.fasterxml.jackson.* in Java/Kotlin sourcesIOException from Jackson calls — these may need
to catch JacksonException (or both during a transition period)throws IOException only because of Jackson —
these can be narrowed to throws JacksonExceptionnew ObjectMapper() configured imperatively, deprecated APIsRead references/jackson2-to-3-changes.md → section "Maven / Gradle Dependency Changes"
for the full GroupId mapping table.
Before writing any version number, query Maven Central for the latest stable release of the BOM:
curl -s "https://search.maven.org/solrsearch/select?q=g:tools.jackson+AND+a:jackson-bom&rows=1&wt=json" \
| jq -r '.response.docs[0].latestVersion'
Use the returned version throughout. Do not default to 3.0.0 without checking —
there may be a newer patch or minor release available.
In the root POM's <dependencyManagement> section, replace all individual Jackson version
declarations with a single BOM import:
<dependencyManagement>
<dependencies>
<!-- Jackson BOM — manages versions for all tools.jackson.* artifacts -->
<dependency>
<groupId>tools.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version><!-- latest from Maven Central --></version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Then in child modules, declare Jackson dependencies without a <version> tag:
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<!-- no version — managed by BOM in root POM -->
</dependency>
Add the BOM to <dependencyManagement> in the same POM, then remove <version> from
individual Jackson dependencies below it.
Remove all com.fasterxml.jackson.* dependencies. Check for:
<dependencies><dependencyManagement><exclusions> that reference old Jackson coordinates (update those too)Mechanical find-and-replace across all source files:
com.fasterxml.jackson → tools.jackson
This covers all sub-packages automatically. Offer to apply this to any files the user provides.
This is the most commonly missed change in Jackson 3.
Many Jackson methods that previously declared throws IOException now declare
throws JacksonException. JacksonException extends IOException, so existing code
compiles — but catch blocks and throws declarations may need updating for correctness
and intent clarity.
Read references/jackson2-to-3-changes.md → section "Exception Changes" for the full
list of affected methods.
// Jackson 2 — catching broad IOException from Jackson operations
try {
MyType obj = mapper.readValue(json, MyType.class);
} catch (IOException e) {
// handle
}
// Jackson 3 — prefer catching JacksonException for Jackson-specific errors
try {
MyType obj = mapper.readValue(json, MyType.class);
} catch (JacksonException e) {
// handle Jackson-specific parse/mapping errors
}
// Jackson 2
public MyType parse(String json) throws IOException {
return mapper.readValue(json, MyType.class);
}
// Jackson 3 — can narrow to JacksonException
public MyType parse(String json) throws JacksonException {
return mapper.readValue(json, MyType.class);
}
Keep throws IOException or catch (IOException e) when the method also does real I/O
(e.g. reading from a File, InputStream, network stream) alongside Jackson calls.
In that case both IOException and JacksonException are valid — JacksonException
extends IOException so the existing IOException catch still works, but you may want
to separate them:
try {
return mapper.readValue(inputStream, MyType.class);
} catch (JacksonException e) {
throw new ParseException("Invalid JSON", e);
} catch (IOException e) {
throw new StorageException("Could not read stream", e);
}
import tools.jackson.core.JacksonException;
Read references/jackson2-to-3-changes.md → section "API Changes" for full details.
// Jackson 2 style (imperative config)
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(new JavaTimeModule());
// Jackson 3 style (builder)
ObjectMapper mapper = JsonMapper.builder()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.addModule(new JavaTimeModule())
.build();
See reference file section "Removed APIs". If any are present in user code, suggest replacements.
For large codebases, recommend OpenRewrite — it handles dependencies, imports, and many API migrations automatically. Show the snippet from the reference file's "OpenRewrite Recipe" section.
Note: OpenRewrite does not currently handle the IOException → JacksonException catch
block narrowing — that must be done manually or with IDE inspections.
⚠️ Critical check: Ask or check if they use Spring Boot.
If they're on Spring Boot 3.x and want Jackson 3, they need to upgrade Spring Boot first.
When migrating files, show a clear before/after diff or provide the updated file. For multi-file migrations, create updated versions of each file. Always summarize: