Reputation: 5
I'm using GSON to serialize an Object using JDK 17.0.10. The object contains XMLGregorianCalendar object which I have registered an adapter for serialization. The compiling of the application is fine but when the application starts, that's where I have issues and get the following exception when calling GsonBuilder.toJson for an object.
com.google.gson.JsonIOException: Failed making field 'com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl#eon' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
at com.google.gson.Gson.getAdapter(Gson.java:556)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:55)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:368)
at com.google.gson.Gson.toJson(Gson.java:842)
at com.google.gson.Gson.toJson(Gson.java:812)
at com.google.gson.Gson.toJson(Gson.java:759)
at com.google.gson.Gson.toJson(Gson.java:736)
I know Java 11 provided warnings when class objects go into the internals of sun API, related to "Strongly Encapsulate JDK Internals by Default" (JEP 396). In the case of Java 17, those issues become errors and the API expects these to be resolved hence the exception I'm getting in the logs.
I've tried using "--add-exports" parameter on startup for the related package with no success. Maybe I was doing it wrong? However, I don't really like doing this and want to fix the problem correctly.
I'm currently using the latest Gson (2.10.1) and have this in my code.
gsonBuilder.registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarSerializer());
I personally believe GSON API is calling "new XMLGregorianCalendar()" when I really need it to call "DatatypeFactory.newInstance().newXMLGregorianCalendar" which would probably solve this issue. My XMLGregorianCalendarSerializer has code where it does evaluation on the contents of the date but I commented it all out to return a new JsonPrimitive with an empty new String object. I did this to remove my serialized logic in my class from the picture so I can focus on what is causing the issue on serialization with Java 17.
So, what am I missing? Is there a way to fix this or am I missing something I need to add to my code to solve this issue? Anybody have any ideas?
Fyi, going to Jackson JSON not a path I want to take. I would like to fix my Gson.
Upvotes: 0
Views: 927
Reputation: 6894
GsonBuilder.registerTypeAdapter
registers the adapter only for the specified class, but not for subclasses. However, XMLGregorianCalendar
is an abstract class and as seen in the exception you are currently receiving, you are actually serializing the JDK-internal subclass XMLGregorianCalendarImpl
.
To solve this use GsonBuilder.registerTypeHierarchyAdapter
instead of registerTypeAdapter
.
Upvotes: 1