0

Referring to this other question, it seems I have a problem with the whole method that I do not understand. In fact, right now I do not have the error specified in the question anymore, but I have a new one:

2019-04-16 16:32:16.843 ERROR 7452 --- [nio-9090-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause

java.lang.StackOverflowError: null
    at java.base/java.nio.CharBuffer.<init>(CharBuffer.java:281) ~[na:na]
    at java.base/java.nio.HeapCharBuffer.<init>(HeapCharBuffer.java:75) ~[na:na]
    at java.base/java.nio.CharBuffer.wrap(CharBuffer.java:393) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:280) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:135) ~[na:na]
    at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:229) ~[na:na]
    at java.base/java.io.Writer.write(Writer.java:249) ~[na:na]
    at com.google.gson.stream.JsonWriter.string(JsonWriter.java:566) ~[gson-2.8.5.jar:na]
    at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402) ~[gson-2.8.5.jar:na]
    at com.google.gson.stream.JsonWriter.value(JsonWriter.java:417) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:406) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:390) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) ~[gson-2.8.5.jar:na]
[...]

In the whole stack trace I have these lines repeating and no info about the line throwing this error. I'm working with flowable and passing data through POST request. The method I'm using is this:

@PostMapping(path = PathConstants.START_ACTION)
    public ResponseEntity<BaseResponse<ProcessInstance>> start(@PathVariable String processDefinitionId,
            @RequestBody(required = false) Map<String, Object> params) throws FileNotFoundException {

        LOGGER.info("starting process definition with id {}", processDefinitionId);

        Map<String, Object> variables;
        ResponseEntity<BaseResponse<ProcessInstance>> response = null;
        PrintStream o = new PrintStream(new File("output.txt"));
        System.setOut(o);
        ProcessInstance pi = null;
        LocalDateTime time = LocalDateTime.now();
        try {
            if (params != null) {           
                pi = runtimeService.startProcessInstanceById(processDefinitionId, params);          
            } else {
                System.out.println("Empty ");
                pi = runtimeService.startProcessInstanceById(processDefinitionId);
            }

            response = new ResponseEntity<>(new BaseResponse<>(Constants.OK, pi), HttpStatus.OK);

            if(pi.isEnded()) {      
                HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().includeProcessVariables().
                        processInstanceId(pi.getId()).singleResult();
                variables = hpi.getProcessVariables();
                System.out.println("Variables " + variables);
                if(variables.get("result").equals("OK")) {
                    MongoOperations.writeLogSuccess(pi, pi.getProcessDefinitionName());
                } else {
                    MongoOperations.writeLogFailure(hpi.getDurationInMillis(), hpi.getStartTime(), pi.getProcessDefinitionName());
                }
            }
            else {
                variables =  runtimeService.getVariables(pi.getId());
            }
        } catch (FlowableObjectNotFoundException e) {
            String pdn = repositoryService.getProcessDefinition(processDefinitionId).getName();
            MongoOperations.writeLogException(time, pdn);
            response = new ResponseEntity<>(new BaseResponse<>(e.getMessage(), null), HttpStatus.NOT_FOUND);
        } catch (FlowableException e) { 
            String pdn = repositoryService.getProcessDefinition(processDefinitionId).getName();
            MongoOperations.writeLogException(time, pdn);
            response = new ResponseEntity<>(new BaseResponse<>(e.getMessage(), null), HttpStatus.INTERNAL_SERVER_ERROR); // other exception are managed here
        } catch (Exception e) {
            String pdn = repositoryService.getProcessDefinition(processDefinitionId).getName();
            MongoOperations.writeLogException(time, pdn);
            response = new ResponseEntity<>(new BaseResponse<>(e.getMessage(), null), HttpStatus.INTERNAL_SERVER_ERROR); // other exception are managed here
        }

        return response;
    }

The method's logic itself is correct, I'm able to do all my operations correctly. This error happens both when Exceptions are thrown or not thrown. Where I can start to check the error?
From the stack trace it appears to be a JsonWriter error, and the only "Json operation" that is done is probably when retrieving the params from the request body, but knowing that how can I fix it? I can't even understand the reason behind this error...

EDIT

So I'm understanding that the possible cause for this error is that Gson does not work well with Object. Is it right? In this case, how can I fix this since my method takes only a Map<String,Object> ?

EDIT 2

Ok so, I've found a workaround but I don't like it, but for now is all I have, and is this:

@PostMapping(path = PathConstants.START_ACTION)
    public ResponseEntity<BaseResponse<ProcessInstance>> start(@PathVariable String processDefinitionId,
            @RequestBody(required = false) Map<?,?> params) throws FileNotFoundException {

        LOGGER.info("starting process definition with id {}", processDefinitionId);

        Map<String, Object> variables = (Map<String, Object>) params;

And then I pass variables to my method. Anyway, a (slightly) new error is thrown:

2019-04-16 17:08:02.638 ERROR 9524 --- [nio-9090-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause

java.lang.StackOverflowError: null
    at org.apache.coyote.Response.isCommitted(Response.java:255) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:179) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.coyote.Response.doWrite(Response.java:599) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:328) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:728) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:657) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[tomcat-embed-core-9.0.14.jar:9.0.14]
    at java.base/sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:233) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:303) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125) ~[na:na]
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:135) ~[na:na]
    at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:229) ~[na:na]
    at com.google.gson.stream.JsonWriter.string(JsonWriter.java:591) ~[gson-2.8.5.jar:na]
    at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:402) ~[gson-2.8.5.jar:na]
    at com.google.gson.stream.JsonWriter.value(JsonWriter.java:417) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:406) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapters$16.write(TypeAdapters.java:390) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127) ~[gson-2.8.5.jar:na]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245) ~[gson-2.8.5.jar:na]
Usr
  • 2,628
  • 10
  • 51
  • 91

1 Answers1

1

The reason why you have those exception is most probably the fact that you are trying to serialize the ProcessInstance. I would highly advise against doing that and creation your own representation that would contain only the information you need.

Gson and Jackson use reflection to perform the serialization. Although the ProcessInstance interface has simple getters, the implementation is much more nuanced and can has a cyclic reference to itself (which is the reason why you re seeing the stackoverflow).

Filip
  • 19,269
  • 7
  • 51
  • 60
  • Hi, I'm not serializing the ProcessInstance, inside the MongoOperation I'm calling I save a custom document with informations retrieved from the ProcessInstance, but not the process instance itself – Usr Apr 18 '19 at 10:17
  • I am talking about the return of your method. You are returning `ResponseEntity>` and the returned response is `response = new ResponseEntity<>(new BaseResponse<>(Constants.OK, pi), HttpStatus.OK);`. Where `pi` is the Flowable `ProcessInstance` – Filip Apr 18 '19 at 11:13