Quarkus从2.8.3.Final升级到3.6.7后GraphQL抛出类型转换异常
Quarkus 3.6.7 GraphQL客户端ClassCastException问题解决
问题场景
升级到Quarkus 3.6.7后,执行GraphQL客户端代码:
var response = client.executeSync(query, variables);
(其中query为字符串类型,variables为Map<String,Object>类型)时抛出ClassCastException,异常栈如下:
java.lang.ClassCastException: class jakarta.json.JsonValueImpl cannot be cast to class jakarta.json.JsonObject (jakarta.json.JsonValueImpl and jakarta.json.JsonObject are in unnamed module of loader 'app') at org.eclipse.parsson.JsonObjectBuilderImpl$JsonObjectImpl.getJsonObject(JsonObjectBuilderImpl.java:234) at io.smallrye.graphql.client.impl.ResponseReader.readFrom(ResponseReader.java:99) at io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClient.lambda$executeSingleResultOperationOverHttp$10(VertxDynamicGraphQLClient.java:451) at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21) at io.smallrye.mutiny.operators.uni.UniOnItemTransform$UniOnItemTransformProcessor.onItem(UniOnItemTransform.java:36) at io.smallrye.mutiny.operators.uni.builders.UniCreateFromCompletionStage$CompletionStageUniSubscription.forwardResult(UniCreateFromCompletionStage.java:63) at io.smallrye.context.impl.wrappers.SlowContextualBiConsumer.accept(SlowContextualBiConsumer.java:21)
服务端返回的响应内容:
{ "data": { "Subscriptions": { "select": [] } }, "errors": [], "extensions": null }
将响应中的"extensions": null替换为"extensions": {}后,功能恢复正常。
原因分析
- 规范兼容性:GraphQL规范定义
extensions字段应为对象类型,不允许为null,但旧服务端可能未遵循该规范返回了null值。 - JSON实现变更:Quarkus 2使用
javax.json相关实现,对extensions: null的场景做了兼容处理;而Quarkus 3切换到Jakarta EE规范的jakarta.json,默认实现为Eclipse Parsson。Parsson的JsonObject.getJsonObject方法在字段值为null时,会返回代表null的JsonValueImpl实例,而非null或空JsonObject,导致代码在强转时抛出异常。
解决方案
可选以下几种方案解决:
- 服务端修复:修改GraphQL服务端代码,确保
extensions字段返回空对象{}而非null,符合GraphQL规范要求。 - 客户端拦截处理:在客户端侧添加响应拦截器,将响应中的
extensions: null替换为extensions: {}后再交给客户端解析。 - 版本补丁:检查Quarkus或SmallRye GraphQL客户端的后续版本,是否有针对该兼容问题的修复补丁,升级到对应版本即可。
内容的提问来源于stack exchange,提问作者Johan Markström
相关产品推荐
相关产品推荐

