Skip to content

Commit 2456a0e

Browse files
authored
Add Support for Jackson 3 (#742)
This change adds Jackson 3 support and aligns package naming in the existing Jackson 2 module. Specific changes: * Deprecated classes for removal in `io.modelcontextprotocol.json.jackson`/`io.modelcontextprotocol.json.schema.jackson` * Copied the above to `io.modelcontextprotocol.json.jackson2`/`io.modelcontextprotocol.json.schema.jackson2` in non-deprecated form. * Added tests for the default McpJsonMapper and JsonSchemaValidator
1 parent af65356 commit 2456a0e

File tree

33 files changed

+2487
-21
lines changed

33 files changed

+2487
-21
lines changed

mcp-core/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
<dependency>
8181
<groupId>com.fasterxml.jackson.core</groupId>
8282
<artifactId>jackson-annotations</artifactId>
83-
<version>${jackson.version}</version>
83+
<version>${jackson-annotations.version}</version>
8484
</dependency>
8585

8686
<dependency>
@@ -100,7 +100,7 @@
100100
<!-- Test dependencies -->
101101
<dependency>
102102
<groupId>io.modelcontextprotocol.sdk</groupId>
103-
<artifactId>mcp-json-jackson2</artifactId>
103+
<artifactId>mcp-json-jackson3</artifactId>
104104
<version>0.18.0-SNAPSHOT</version>
105105
<scope>test</scope>
106106
</dependency>

mcp-core/src/test/java/io/modelcontextprotocol/spec/McpSchemaTests.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.assertj.core.api.Assertions.assertThat;
1111
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1212

13+
import java.io.IOException;
1314
import java.util.Arrays;
1415
import java.util.Collections;
1516
import java.util.HashMap;
@@ -18,7 +19,7 @@
1819

1920
import org.junit.jupiter.api.Test;
2021

21-
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
22+
import tools.jackson.databind.exc.InvalidTypeIdException;
2223

2324
import io.modelcontextprotocol.spec.McpSchema.TextResourceContents;
2425
import net.javacrumbs.jsonunit.core.Option;
@@ -58,7 +59,9 @@ void testTextContentDeserialization() throws Exception {
5859
void testContentDeserializationWrongType() throws Exception {
5960

6061
assertThatThrownBy(() -> JSON_MAPPER.readValue("""
61-
{"type":"WRONG","text":"XXX"}""", McpSchema.TextContent.class))
62+
{"type":"WRONG","text":"XXX"}""", McpSchema.TextContent.class)).isInstanceOf(IOException.class)
63+
.hasMessage("Failed to read value")
64+
.cause()
6265
.isInstanceOf(InvalidTypeIdException.class)
6366
.hasMessageContaining(
6467
"Could not resolve type id 'WRONG' as a subtype of `io.modelcontextprotocol.spec.McpSchema$TextContent`: known type ids = [audio, image, resource, resource_link, text]");

mcp-json-jackson2/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<artifactId>mcp-json-jackson2</artifactId>
1212
<packaging>jar</packaging>
1313
<name>Java MCP SDK JSON Jackson</name>
14-
<description>Java MCP SDK JSON implementation based on Jackson</description>
14+
<description>Java MCP SDK JSON implementation based on Jackson 2</description>
1515
<url>https://github.com/modelcontextprotocol/java-sdk</url>
1616
<scm>
1717
<url>https://github.com/modelcontextprotocol/java-sdk</url>
@@ -42,12 +42,12 @@
4242
<dependency>
4343
<groupId>com.fasterxml.jackson.core</groupId>
4444
<artifactId>jackson-databind</artifactId>
45-
<version>${jackson.version}</version>
45+
<version>${jackson2.version}</version>
4646
</dependency>
4747
<dependency>
4848
<groupId>com.networknt</groupId>
4949
<artifactId>json-schema-validator</artifactId>
50-
<version>${json-schema-validator.version}</version>
50+
<version>${json-schema-validator-jackson2.version}</version>
5151
</dependency>
5252

5353
<dependency>

mcp-json-jackson2/src/main/java/io/modelcontextprotocol/json/jackson/JacksonMcpJsonMapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@
1414
/**
1515
* Jackson-based implementation of JsonMapper. Wraps a Jackson ObjectMapper but keeps the
1616
* SDK decoupled from Jackson at the API level.
17+
*
18+
* @deprecated since 18.0.0, use
19+
* {@link io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapper} instead. Will be
20+
* removed in 19.0.0
1721
*/
22+
@Deprecated(forRemoval = true, since = "18.0.0")
1823
public final class JacksonMcpJsonMapper implements McpJsonMapper {
1924

2025
private final ObjectMapper objectMapper;

mcp-json-jackson2/src/main/java/io/modelcontextprotocol/json/jackson/JacksonMcpJsonMapperSupplier.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
* <p>
1414
* This implementation provides a {@link McpJsonMapper} backed by a Jackson
1515
* {@link com.fasterxml.jackson.databind.ObjectMapper}.
16+
*
17+
* @deprecated since 18.0.0, use
18+
* {@link io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapperSupplier} instead.
19+
* Will be removed in 19.0.0.
1620
*/
21+
@Deprecated(forRemoval = true, since = "18.0.0")
1722
public class JacksonMcpJsonMapperSupplier implements McpJsonMapperSupplier {
1823

1924
/**
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2026 - 2026 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol.json.jackson2;
6+
7+
import java.io.IOException;
8+
9+
import com.fasterxml.jackson.databind.JavaType;
10+
import com.fasterxml.jackson.databind.ObjectMapper;
11+
12+
import io.modelcontextprotocol.json.McpJsonMapper;
13+
import io.modelcontextprotocol.json.TypeRef;
14+
15+
/**
16+
* Jackson-based implementation of JsonMapper. Wraps a Jackson ObjectMapper but keeps the
17+
* SDK decoupled from Jackson at the API level.
18+
*/
19+
public final class JacksonMcpJsonMapper implements McpJsonMapper {
20+
21+
private final ObjectMapper objectMapper;
22+
23+
/**
24+
* Constructs a new JacksonMcpJsonMapper instance with the given ObjectMapper.
25+
* @param objectMapper the ObjectMapper to be used for JSON serialization and
26+
* deserialization. Must not be null.
27+
* @throws IllegalArgumentException if the provided ObjectMapper is null.
28+
*/
29+
public JacksonMcpJsonMapper(ObjectMapper objectMapper) {
30+
if (objectMapper == null) {
31+
throw new IllegalArgumentException("ObjectMapper must not be null");
32+
}
33+
this.objectMapper = objectMapper;
34+
}
35+
36+
/**
37+
* Returns the underlying Jackson {@link ObjectMapper} used for JSON serialization and
38+
* deserialization.
39+
* @return the ObjectMapper instance
40+
*/
41+
public ObjectMapper getObjectMapper() {
42+
return objectMapper;
43+
}
44+
45+
@Override
46+
public <T> T readValue(String content, Class<T> type) throws IOException {
47+
return objectMapper.readValue(content, type);
48+
}
49+
50+
@Override
51+
public <T> T readValue(byte[] content, Class<T> type) throws IOException {
52+
return objectMapper.readValue(content, type);
53+
}
54+
55+
@Override
56+
public <T> T readValue(String content, TypeRef<T> type) throws IOException {
57+
JavaType javaType = objectMapper.getTypeFactory().constructType(type.getType());
58+
return objectMapper.readValue(content, javaType);
59+
}
60+
61+
@Override
62+
public <T> T readValue(byte[] content, TypeRef<T> type) throws IOException {
63+
JavaType javaType = objectMapper.getTypeFactory().constructType(type.getType());
64+
return objectMapper.readValue(content, javaType);
65+
}
66+
67+
@Override
68+
public <T> T convertValue(Object fromValue, Class<T> type) {
69+
return objectMapper.convertValue(fromValue, type);
70+
}
71+
72+
@Override
73+
public <T> T convertValue(Object fromValue, TypeRef<T> type) {
74+
JavaType javaType = objectMapper.getTypeFactory().constructType(type.getType());
75+
return objectMapper.convertValue(fromValue, javaType);
76+
}
77+
78+
@Override
79+
public String writeValueAsString(Object value) throws IOException {
80+
return objectMapper.writeValueAsString(value);
81+
}
82+
83+
@Override
84+
public byte[] writeValueAsBytes(Object value) throws IOException {
85+
return objectMapper.writeValueAsBytes(value);
86+
}
87+
88+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2026 - 2026 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol.json.jackson2;
6+
7+
import io.modelcontextprotocol.json.McpJsonMapper;
8+
import io.modelcontextprotocol.json.McpJsonMapperSupplier;
9+
10+
/**
11+
* A supplier of {@link McpJsonMapper} instances that uses the Jackson library for JSON
12+
* serialization and deserialization.
13+
* <p>
14+
* This implementation provides a {@link McpJsonMapper} backed by a Jackson
15+
* {@link com.fasterxml.jackson.databind.ObjectMapper}.
16+
*/
17+
public class JacksonMcpJsonMapperSupplier implements McpJsonMapperSupplier {
18+
19+
/**
20+
* Returns a new instance of {@link McpJsonMapper} that uses the Jackson library for
21+
* JSON serialization and deserialization.
22+
* <p>
23+
* The returned {@link McpJsonMapper} is backed by a new instance of
24+
* {@link com.fasterxml.jackson.databind.ObjectMapper}.
25+
* @return a new {@link McpJsonMapper} instance
26+
*/
27+
@Override
28+
public McpJsonMapper get() {
29+
return new JacksonMcpJsonMapper(new com.fasterxml.jackson.databind.ObjectMapper());
30+
}
31+
32+
}

mcp-json-jackson2/src/main/java/io/modelcontextprotocol/json/schema/jackson/DefaultJsonSchemaValidator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
* NetworkNT JSON Schema Validator library for validation.
2525
*
2626
* @author Christian Tzolov
27+
* @deprecated since 18.0.0, use
28+
* {@link io.modelcontextprotocol.json.schema.jackson2.DefaultJsonSchemaValidator}
29+
* instead. Will be removed in 19.0.0.
2730
*/
31+
@Deprecated(forRemoval = true, since = "18.0.0")
2832
public class DefaultJsonSchemaValidator implements JsonSchemaValidator {
2933

3034
private static final Logger logger = LoggerFactory.getLogger(DefaultJsonSchemaValidator.class);

mcp-json-jackson2/src/main/java/io/modelcontextprotocol/json/schema/jackson/JacksonJsonSchemaValidatorSupplier.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
*
1414
* @see JsonSchemaValidatorSupplier
1515
* @see JsonSchemaValidator
16+
* @deprecated since 18.0.0, use
17+
* {@link io.modelcontextprotocol.json.schema.jackson2.JacksonJsonSchemaValidatorSupplier}
18+
* instead. Will be removed in 19.0.0.
1619
*/
1720
public class JacksonJsonSchemaValidatorSupplier implements JsonSchemaValidatorSupplier {
1821

0 commit comments

Comments
 (0)