Skip to content

Commit 7d7749a

Browse files
committed
Upgrade to Spring Framework 7.0.0-M5
This commit also adapts to the new Jackson 3.0 baseline. Closes gh-1202
1 parent ce90154 commit 7d7749a

File tree

39 files changed

+462
-161
lines changed

39 files changed

+462
-161
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ description = "Spring for GraphQL"
22

33
ext {
44
moduleProjects = [project(":spring-graphql"), project(":spring-graphql-test")]
5-
springFrameworkVersion = "7.0.0-M4"
5+
springFrameworkVersion = "7.0.0-M5"
66
graphQlJavaVersion = "24.0"
77
springBootVersion = "3.4.3"
88
}

platform/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ javaPlatform {
88

99
dependencies {
1010
api(platform("org.springframework:spring-framework-bom:${springFrameworkVersion}"))
11-
api(platform("com.fasterxml.jackson:jackson-bom:2.18.3"))
11+
api(platform("tools.jackson:jackson-bom:3.0.0-rc4"))
1212
api(platform("io.projectreactor:reactor-bom:2025.0.0-M3"))
1313
api(platform("io.micrometer:micrometer-bom:1.15.0"))
1414
api(platform("io.micrometer:micrometer-tracing-bom:1.5.0"))

spring-graphql-docs/modules/ROOT/pages/data.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,8 @@ You can then create `JsonKeysetCursorStrategy`:
452452
ObjectMapper mapper = ... ;
453453
454454
CodecConfigurer configurer = ServerCodecConfigurer.create();
455-
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper));
456-
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper));
455+
configurer.defaultCodecs().jacksonJsonDecoder(new JacksonJsonDecoder(mapper));
456+
configurer.defaultCodecs().jacksonJsonEncoder(new JacksonJsonEncoder(mapper));
457457
458458
JsonKeysetCursorStrategy strategy = new JsonKeysetCursorStrategy(configurer);
459459
----

spring-graphql-test/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies {
1414
compileOnly 'org.springframework:spring-websocket'
1515
compileOnly 'org.springframework:spring-messaging'
1616
compileOnly 'jakarta.servlet:jakarta.servlet-api'
17+
compileOnly 'tools.jackson.core:jackson-databind'
1718
compileOnly 'io.rsocket:rsocket-core'
1819
compileOnly 'io.rsocket:rsocket-transport-netty'
1920
compileOnly 'org.skyscreamer:jsonassert'
@@ -32,7 +33,7 @@ dependencies {
3233
testImplementation 'io.projectreactor.netty:reactor-netty'
3334
testImplementation 'io.rsocket:rsocket-transport-local'
3435
testImplementation 'io.micrometer:context-propagation'
35-
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
36+
testImplementation 'tools.jackson.core:jackson-databind'
3637

3738
testRuntimeOnly 'org.apache.logging.log4j:log4j-core'
3839
testRuntimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl'

spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractGraphQlTesterBuilder.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import java.util.function.Predicate;
2525

2626
import com.jayway.jsonpath.Configuration;
27-
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
28-
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
2927
import com.jayway.jsonpath.spi.mapper.MappingProvider;
3028
import org.jspecify.annotations.Nullable;
3129
import reactor.core.publisher.Flux;
@@ -60,8 +58,8 @@
6058
*/
6159
public abstract class AbstractGraphQlTesterBuilder<B extends AbstractGraphQlTesterBuilder<B>> implements GraphQlTester.Builder<B> {
6260

63-
private static final boolean jackson2Present = ClassUtils.isPresent(
64-
"com.fasterxml.jackson.databind.ObjectMapper", AbstractGraphQlClientBuilder.class.getClassLoader());
61+
private static final boolean jacksonPresent = ClassUtils.isPresent(
62+
"tools.jackson.databind.ObjectMapper", AbstractGraphQlClientBuilder.class.getClassLoader());
6563

6664
private static final Duration DEFAULT_RESPONSE_DURATION = Duration.ofSeconds(5);
6765

@@ -130,8 +128,8 @@ protected void configureJsonPathConfig(Function<Configuration, Configuration> co
130128
*/
131129
protected GraphQlTester buildGraphQlTester(GraphQlTransport transport) {
132130

133-
if (jackson2Present) {
134-
configureJsonPathConfig(Jackson2Configurer::configure);
131+
if (jacksonPresent) {
132+
configureJsonPathConfig(JacksonConfigurer::configure);
135133
}
136134

137135
return new DefaultGraphQlTester(transport, this.errorFilter,
@@ -195,7 +193,7 @@ private static void copyAttributes(Map<String, Object> map, GraphQlRequest reque
195193
}
196194

197195

198-
private static final class Jackson2Configurer {
196+
private static final class JacksonConfigurer {
199197

200198
private static final Class<?> defaultJsonProviderType;
201199

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2020-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.graphql.test.tester;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.io.InputStreamReader;
22+
import java.io.StringWriter;
23+
import java.util.LinkedHashMap;
24+
import java.util.LinkedList;
25+
26+
import com.jayway.jsonpath.InvalidJsonException;
27+
import com.jayway.jsonpath.spi.json.AbstractJsonProvider;
28+
import tools.jackson.core.JacksonException;
29+
import tools.jackson.core.JsonGenerator;
30+
import tools.jackson.databind.ObjectMapper;
31+
import tools.jackson.databind.ObjectReader;
32+
33+
/**
34+
* {@link com.jayway.jsonpath.spi.json.JsonProvider} for Jackson 3.x.
35+
* @author Brian Clozel
36+
*/
37+
class JacksonJsonProvider extends AbstractJsonProvider {
38+
39+
private final ObjectMapper objectMapper = new ObjectMapper();
40+
41+
private final ObjectReader objectReader = this.objectMapper.reader();
42+
43+
@Override
44+
public Object parse(String json) throws InvalidJsonException {
45+
try {
46+
return this.objectReader.readValue(json);
47+
}
48+
catch (JacksonException exc) {
49+
throw new InvalidJsonException(exc, json);
50+
}
51+
}
52+
53+
@Override
54+
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
55+
try {
56+
return this.objectReader.readValue(new InputStreamReader(jsonStream, charset));
57+
}
58+
catch (IOException exc) {
59+
throw new InvalidJsonException(exc);
60+
}
61+
}
62+
63+
@Override
64+
public String toJson(Object obj) {
65+
StringWriter writer = new StringWriter();
66+
try {
67+
JsonGenerator generator = this.objectMapper.createGenerator(writer);
68+
this.objectMapper.writeValue(generator, obj);
69+
writer.flush();
70+
writer.close();
71+
generator.close();
72+
return writer.getBuffer().toString();
73+
}
74+
catch (IOException exc) {
75+
throw new InvalidJsonException(exc);
76+
}
77+
}
78+
79+
@Override
80+
public Object createArray() {
81+
return new LinkedList<Object>();
82+
}
83+
84+
@Override
85+
public Object createMap() {
86+
return new LinkedHashMap<String, Object>();
87+
}
88+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2020-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.graphql.test.tester;
18+
19+
import com.jayway.jsonpath.Configuration;
20+
import com.jayway.jsonpath.TypeRef;
21+
import com.jayway.jsonpath.spi.mapper.MappingException;
22+
import com.jayway.jsonpath.spi.mapper.MappingProvider;
23+
import org.jspecify.annotations.Nullable;
24+
import tools.jackson.databind.JavaType;
25+
import tools.jackson.databind.ObjectMapper;
26+
27+
/**
28+
* {@link MappingProvider} for Jackson 3.x.
29+
* @author Brian Clozel
30+
*/
31+
class JacksonMappingProvider implements MappingProvider {
32+
33+
private final ObjectMapper objectMapper = new ObjectMapper();
34+
35+
@Override
36+
public <T> @Nullable T map(@Nullable Object source, Class<T> targetType, Configuration configuration) {
37+
if (source == null) {
38+
return null;
39+
}
40+
try {
41+
return this.objectMapper.convertValue(source, targetType);
42+
}
43+
catch (Exception exc) {
44+
throw new MappingException(exc);
45+
}
46+
47+
}
48+
49+
@Override
50+
@SuppressWarnings("unchecked")
51+
public <T> @Nullable T map(@Nullable Object source, final TypeRef<T> targetType, Configuration configuration) {
52+
if (source == null) {
53+
return null;
54+
}
55+
JavaType type = this.objectMapper.getTypeFactory().constructType(targetType.getType());
56+
57+
try {
58+
return (T) this.objectMapper.convertValue(source, type);
59+
}
60+
catch (Exception exc) {
61+
throw new MappingException(exc);
62+
}
63+
64+
}
65+
}

spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterBuilderTests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,8 +31,8 @@
3131
import org.springframework.graphql.ExecutionGraphQlRequest;
3232
import org.springframework.graphql.ExecutionGraphQlService;
3333
import org.springframework.graphql.support.DocumentSource;
34-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
35-
import org.springframework.http.codec.json.Jackson2JsonEncoder;
34+
import org.springframework.http.codec.json.JacksonJsonDecoder;
35+
import org.springframework.http.codec.json.JacksonJsonEncoder;
3636
import org.springframework.lang.Nullable;
3737
import org.springframework.util.MimeType;
3838

@@ -91,10 +91,10 @@ void mutateDocumentSource() {
9191
@Test
9292
void codecConfigurerRegistersJsonPathMappingProvider() {
9393

94-
TestJackson2JsonDecoder testDecoder = new TestJackson2JsonDecoder();
94+
TestJacksonJsonDecoder testDecoder = new TestJacksonJsonDecoder();
9595

9696
ExecutionGraphQlServiceTester.Builder<?> builder = graphQlTesterBuilder()
97-
.encoder(new Jackson2JsonEncoder())
97+
.encoder(new JacksonJsonEncoder())
9898
.decoder(testDecoder);
9999

100100
String document = "{me {name}}";
@@ -138,7 +138,7 @@ void errorsFilteredGlobally() {
138138
}
139139

140140

141-
private static class TestJackson2JsonDecoder extends Jackson2JsonDecoder {
141+
private static class TestJacksonJsonDecoder extends JacksonJsonDecoder {
142142

143143
@Nullable
144144
private Object lastValue;

spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/RSocketGraphQlTesterBuilderTests.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,8 +36,8 @@
3636
import org.springframework.graphql.GraphQlRequest;
3737
import org.springframework.graphql.execution.MockExecutionGraphQlService;
3838
import org.springframework.graphql.server.GraphQlRSocketHandler;
39-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
40-
import org.springframework.http.codec.json.Jackson2JsonEncoder;
39+
import org.springframework.http.codec.json.JacksonJsonDecoder;
40+
import org.springframework.http.codec.json.JacksonJsonEncoder;
4141
import org.springframework.lang.Nullable;
4242
import org.springframework.messaging.handler.annotation.MessageMapping;
4343
import org.springframework.messaging.rsocket.RSocketStrategies;
@@ -87,12 +87,12 @@ void mutate() {
8787
@Test
8888
void rsocketStrategiesRegistersJsonPathMappingProvider() {
8989

90-
TestJackson2JsonDecoder testDecoder = new TestJackson2JsonDecoder();
90+
TestJacksonJsonDecoder testDecoder = new TestJacksonJsonDecoder();
9191

9292
RSocketGraphQlTester.Builder<?> builder = this.builderSetup.initBuilder()
9393
.rsocketRequester(requesterBuilder -> {
9494
RSocketStrategies strategies = RSocketStrategies.builder()
95-
.encoder(new Jackson2JsonEncoder())
95+
.encoder(new JacksonJsonEncoder())
9696
.decoder(testDecoder)
9797
.build();
9898
requesterBuilder.rsocketStrategies(strategies);
@@ -132,7 +132,7 @@ public BuilderSetup() {
132132
public RSocketGraphQlTester.Builder<?> initBuilder() {
133133

134134
GraphQlRSocketController controller = new GraphQlRSocketController(
135-
new GraphQlRSocketHandler(this.graphQlService, Collections.emptyList(), new Jackson2JsonEncoder()));
135+
new GraphQlRSocketHandler(this.graphQlService, Collections.emptyList(), new JacksonJsonEncoder()));
136136

137137
this.server = RSocketServer.create()
138138
.acceptor(createSocketAcceptor(controller))
@@ -146,8 +146,8 @@ public RSocketGraphQlTester.Builder<?> initBuilder() {
146146
private SocketAcceptor createSocketAcceptor(GraphQlRSocketController controller) {
147147

148148
RSocketStrategies.Builder builder = RSocketStrategies.builder();
149-
builder.encoder(new Jackson2JsonEncoder());
150-
builder.decoder(new Jackson2JsonDecoder());
149+
builder.encoder(new JacksonJsonEncoder());
150+
builder.decoder(new JacksonJsonDecoder());
151151

152152
RSocketMessageHandler handler = new RSocketMessageHandler();
153153
handler.setHandlers(Collections.singletonList(controller));
@@ -195,7 +195,7 @@ public Flux<Map<String, Object>> handleSubscription(Map<String, Object> payload)
195195
}
196196

197197

198-
private static class TestJackson2JsonDecoder extends Jackson2JsonDecoder {
198+
private static class TestJacksonJsonDecoder extends JacksonJsonDecoder {
199199

200200
@Nullable
201201
private Object lastValue;

spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/WebGraphQlTesterBuilderTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
4242
import org.springframework.graphql.server.webflux.GraphQlWebSocketHandler;
4343
import org.springframework.graphql.support.DocumentSource;
4444
import org.springframework.http.codec.ClientCodecConfigurer;
45-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
45+
import org.springframework.http.codec.json.JacksonJsonDecoder;
4646
import org.springframework.lang.Nullable;
4747
import org.springframework.test.web.reactive.server.WebTestClient;
4848
import org.springframework.util.Assert;
@@ -168,7 +168,7 @@ void mutateDocumentSource(TesterBuilderSetup builderSetup) {
168168
@MethodSource("argumentSource")
169169
void codecConfigurerRegistersJsonPathMappingProvider(TesterBuilderSetup builderSetup) {
170170

171-
TestJackson2JsonDecoder testDecoder = new TestJackson2JsonDecoder();
171+
TestJacksonJsonDecoder testDecoder = new TestJacksonJsonDecoder();
172172

173173
WebGraphQlTester.Builder<?> builder = builderSetup.initBuilder()
174174
.codecConfigurer(codecConfigurer -> codecConfigurer.customCodecs().register(testDecoder));
@@ -267,7 +267,7 @@ public WebSocketGraphQlTester.Builder<?> initBuilder() {
267267
}
268268

269269

270-
private static class TestJackson2JsonDecoder extends Jackson2JsonDecoder {
270+
private static class TestJacksonJsonDecoder extends JacksonJsonDecoder {
271271

272272
@Nullable
273273
private Object lastValue;

0 commit comments

Comments
 (0)