3

I have the following Java object.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
    name = "ApprovalRequest",
    propOrder = {"requiredConclusionTime", "approvalType", "businessRequest", "supportingInfo", "messageToEvaluator", "organisation", "resubmissionOf", "requestedBy", "nominatedEvaluator", "evaluationStrategy"}
)
public class ApprovalRequest implements Serializable {
    private static final long serialVersionUID = 1L;
    @XmlSchemaType(
        name = "dateTime"
    )
    protected XMLGregorianCalendar requiredConclusionTime;
    protected Integer approvalType;
    @XmlElement(
        required = true
    )
    protected Object businessRequest;
    protected List<Object> supportingInfo;
    protected String messageToEvaluator;
    @XmlElement(
        required = true
    )
    @XmlSchemaType(
        name = "anyURI"
    )
    protected String organisation;
    protected String resubmissionOf;
    protected PersonalInfo requestedBy;
    protected EvaluatorNomination nominatedEvaluator;
    protected EvaluationStrategy evaluationStrategy;

    public ApprovalRequest() {
    }

    public XMLGregorianCalendar getRequiredConclusionTime() {
        return this.requiredConclusionTime;
    }

    public void setRequiredConclusionTime(XMLGregorianCalendar value) {
        this.requiredConclusionTime = value;
    }

    public Integer getApprovalType() {
        return this.approvalType;
    }

    public void setApprovalType(Integer value) {
        this.approvalType = value;
    }

    public Object getBusinessRequest() {
        return this.businessRequest;
    }

    public void setBusinessRequest(Object value) {
        this.businessRequest = value;
    }

    public List<Object> getSupportingInfo() {
        if (this.supportingInfo == null) {
            this.supportingInfo = new ArrayList();
        }

        return this.supportingInfo;
    }

    public String getMessageToEvaluator() {
        return this.messageToEvaluator;
    }

    public void setMessageToEvaluator(String value) {
        this.messageToEvaluator = value;
    }

    public String getOrganisation() {
        return this.organisation;
    }

    public void setOrganisation(String value) {
        this.organisation = value;
    }

    public String getResubmissionOf() {
        return this.resubmissionOf;
    }

    public void setResubmissionOf(String value) {
        this.resubmissionOf = value;
    }

    public PersonalInfo getRequestedBy() {
        return this.requestedBy;
    }

    public void setRequestedBy(PersonalInfo value) {
        this.requestedBy = value;
    }

    public EvaluatorNomination getNominatedEvaluator() {
        return this.nominatedEvaluator;
    }

    public void setNominatedEvaluator(EvaluatorNomination value) {
        this.nominatedEvaluator = value;
    }

    public EvaluationStrategy getEvaluationStrategy() {
        return this.evaluationStrategy;
    }

    public void setEvaluationStrategy(EvaluationStrategy value) {
        this.evaluationStrategy = value;
    }
}

When I do the following:

ApprovalRequest approvalRequest = new ApprovalRequest();
Gson gson = new Gson();
String approvalRequestJsonStr = gson.toJson(approvalRequest);

It works perfectly.

However, when I let the application run on the JBoss server, and at runtime with a populated ApprovalRequest, there's an exception converting the object to JSON.

Gson gson = new Gson();
String approvalRequestJsonStr = gson.toJson(approvalRequest);

Gets the following error:

Caused by: java.lang.StackOverflowError
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.stream.JsonWriter.peek(JsonWriter.java:350)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.stream.JsonWriter.beforeName(JsonWriter.java:565)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:386)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.stream.JsonWriter.value(JsonWriter.java:402)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:353)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.TypeAdapters$13.write(TypeAdapters.java:337)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
18:40:26,836 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.ObjectTypeAdapter.write(ObjectTypeAdapter.java:105)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
18:40:26,837 ERROR [stderr] (http--0.0.0.0-8443-1)  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
...

Any ideas how I can fix this?

PM 77-1
  • 12,933
  • 21
  • 68
  • 111
Richard
  • 8,193
  • 28
  • 107
  • 228
  • You're almost certainly trying to serialise an object that contains a reference to itself - not directly, but maybe in the supportinginfo, businessrequest, etc. objects - and that will cause an infinite recursive loop when you try to serialise it. – Michael Berry Jun 27 '20 at 17:03
  • What are you sending in `supportingInfo` field? This may be the culprit. – Anish B. Jun 27 '20 at 17:11
  • 1
    @PM, thanks fro the reply. Yes, I think you are correct. It is a pretty complex object, which is used by another system, I am just trying to passing it to a proxy and then pass it to the other system. I have set up the proxy to use a Spring RESTful Resource to consume the 'approvalRequest', where the original system used a SOAP webservice. Do you think I would be better not to try convert it to JSON, and rather try convert it to XML (because that's what the SOAP envelop is)? – Richard Jun 27 '20 at 17:12
  • @Richard - I did not post any comments. You gratitude belongs to someone else. – PM 77-1 Jun 27 '20 at 17:14
  • @PM77-1 LOL !! :D – Anish B. Jun 27 '20 at 17:16
  • 1
    The 'BusinessRequest' and 'SupportingInfo' are `ElementNSImpl` (`org.w3c.domNode`). The `ApprovalRequest` object is unfortunately from a library I don't have control over and is used by other systems too, so I cannot change it. – Richard Jun 27 '20 at 17:16
  • Using `Gson` you can mark the fields you do want to be included in json with @Expose. – Amit kumar Jun 27 '20 at 17:18
  • I need to include all the fields unfortunately . Is there perhaps a way to serialize the object? Then pass that serialized object as a String to the service and then deserialize it on the other side. i.e. not use JSON – Richard Jun 27 '20 at 17:21
  • I think I need to rather send an XML object – Richard Jun 27 '20 at 18:54
  • There is a workaround with using a custom serializer - see [this question](https://stackoverflow.com/questions/10036958/the-easiest-way-to-remove-the-bidirectional-recursive-relationships). – Tomas Zezula Jul 08 '20 at 14:44

0 Answers0