skip to Main Content

Somehow below code is failing even after creating a custom type adapter. Its working for other type like string. Any idea how can I resolve the issue. Below is the code:

package com;

import java.io.IOException;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

public class DateConversion {

    public static void main(String[] args) throws DatatypeConfigurationException {

        XMLGregorianCalendar date = DatatypeFactory.newInstance().newXMLGregorianCalendar();

        Request req = new Request();
        req.setDate(date);
        TypeAdapter<XMLGregorianCalendar> adapter = new TypeAdapter<XMLGregorianCalendar>() {

            @Override
            public void write(JsonWriter writer, XMLGregorianCalendar value) throws IOException {
                System.out.println("Inside write");
                if(value==null) {
                    writer.nullValue();
                    return;
                }
                writer.value("value");

            }

            @Override
            public XMLGregorianCalendar read(JsonReader reader) throws IOException {
                System.out.println("Inside read");
                return null;
            }
        };
        Gson gsonBuilder = (new GsonBuilder()).registerTypeAdapter(XMLGregorianCalendar.class, adapter).serializeNulls().create();
        System.out.println(gsonBuilder.toJson(req));
    }

}

class Request {
    private XMLGregorianCalendar date;

    public XMLGregorianCalendar getDate() {
        return date;
    }

    public void setDate(XMLGregorianCalendar date) {
        this.date = date;
    }
}

And below is the error stacktrace:

Exception in thread "main" com.google.gson.JsonIOException: Failed making field 'com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl#eon' accessible; either change its visibility or write a custom TypeAdapter for its declaring type

Java object should be successfully parsed to JSON but it is not working

2

Answers


  1. I’m guessing that you are using Java 17+.

    As of Java 17, the module system is enforced and java-xml doesn’t export the internal classes for other modules to use.

    See: https://github.com/openjdk/jdk17/blob/74007890bb9a3fa3a65683a3f480e399f2b1a0b6/src/java.xml/share/classes/module-info.java

    This is why XMLGregorianCalendarImpl‘s fields are not available to the GsonBuilder.

    https://github.com/openjdk/jdk17/blob/74007890bb9a3fa3a65683a3f480e399f2b1a0b6/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java

    I don’t think that GsonBuilder can use an object’s getters and setters.

    So you need to make a proper TypeAdapter should map all the getters and setters in XMLGregorianCalendar to an object that can be serialized, something like LocalDate.

    https://github.com/openjdk/jdk17/blob/74007890bb9a3fa3a65683a3f480e399f2b1a0b6/src/java.xml/share/classes/javax/xml/datatype/XMLGregorianCalendar.java

    Or you simply switch from XMLGregorianCalendar to LocalDate?

    Login or Signup to reply.
  2. The reason why Gson is unable to make fields of that class accessible is a combination of the JDK restricting access to implementation details and Gson not having a built-in adapter for XMLGregorianCalendar so it falls back to using reflection.

    Though it sounds your question is rather why your custom adapter is not called. The answer for this is most likely that (as seen in the exception message) you are not actually serializing an object of type XMLGregorianCalendar, but a JDK internal subclass. However, GsonBuilder.registerTypeAdapter which you are using registers the adapter for that specific class and not for subclasses.

    To solve this you should use GsonBuilder.registerTypeHierarchyAdapter instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search