You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17中Gson序列化XMLGregorianCalendar遇权限异常的解决问询

解决JDK 17下Gson序列化XMLGregorianCalendar的权限异常问题

核心问题分析

你遇到的报错本质是Gson默认通过反射序列化XMLGregorianCalendar时,直接访问了JDK 17封装的内部实现类XMLGregorianCalendarImpl的私有字段,而JEP 396强化了内部API的访问限制。注释自定义适配器仍报错,说明你的适配器未被Gson正确识别,它仍在走默认的反射逻辑。

可行解决方案

1. 确保自定义适配器正确注册并优先生效

必须将适配器绑定到XMLGregorianCalendar接口(而非内部实现类),且在创建Gson实例时优先注册,避免Gson触发反射逻辑。

示例代码:

public class XMLGregorianCalendarSerializer implements JsonSerializer<XMLGregorianCalendar> {
    @Override
    public JsonElement serialize(XMLGregorianCalendar calendar, Type type, JsonSerializationContext context) {
        // 自定义序列化逻辑:转为标准XML格式字符串
        return calendar == null ? JsonNull.INSTANCE : new JsonPrimitive(calendar.toXMLFormat());
    }
}

// 注册适配器并创建Gson实例
Gson gson = new GsonBuilder()
    .registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarSerializer())
    .create();

2. 使用TypeAdapterFactory彻底接管类型处理

如果直接注册JsonSerializer仍不生效,改用TypeAdapterFactory可以更精准地拦截Gson对XMLGregorianCalendar类型的处理,完全绕过反射:

public class XMLGregorianCalendarAdapterFactory implements TypeAdapterFactory {
    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
        if (XMLGregorianCalendar.class.isAssignableFrom(typeToken.getRawType())) {
            return (TypeAdapter<T>) new TypeAdapter<XMLGregorianCalendar>() {
                @Override
                public void write(JsonWriter writer, XMLGregorianCalendar calendar) throws IOException {
                    if (calendar == null) {
                        writer.nullValue();
                        return;
                    }
                    writer.value(calendar.toXMLFormat());
                }

                @Override
                public XMLGregorianCalendar read(JsonReader reader) throws IOException {
                    // 若需反序列化,添加对应的解析逻辑
                    try {
                        return DatatypeFactory.newInstance().newXMLGregorianCalendar(reader.nextString());
                    } catch (DatatypeConfigurationException e) {
                        throw new IOException("Failed to parse XMLGregorianCalendar", e);
                    }
                }
            };
        }
        return null;
    }
}

// 注册Factory
Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new XMLGregorianCalendarAdapterFactory())
    .create();

3. 升级Gson到兼容JDK 17的版本

Gson 2.10.1对JDK 17的内部API访问处理存在缺陷,升级到2.11.0及以上版本,官方已修复了部分JDK 17下的反射权限问题,可能无需自定义适配器即可正常序列化。

关键注意事项

  • 不要尝试绑定适配器到XMLGregorianCalendarImpl,该类是JDK内部实现,属于未公开API,JDK 17严格限制外部访问。
  • 确保你的自定义适配器逻辑中仅使用XMLGregorianCalendar接口的公开方法(如toXMLFormat()),避免直接操作内部字段。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:47:20