Search code examples
javaaxon

Axon query returning list with Axon Server


We have an application where we're trying to move from using just the Axon Framework to also using the Axon Server. We're experiencing an issue where query responses, which are multiple instances of a type, are failing to be properly transported. The issue as detailed below does not occur when the server is not being used.

We're sending a query and expecting a list of a specific type as the response.

queryGateway.query(new MyQuery(...), ResponseTypes.multipleInstancesOf(MyResponse.class));

// elsewhere
@QueryHandler
public List<MyResponse> handle(MyQueryquery) {
  return List.of(new MyResponse(...));
}

When run without the server this works fine. Of interest is that MultipleInstancesResponseType#convert(Object) is called once, and the parameter is the List<MyResponse> instance. No conversion is necessary here.

When run with the server MultipleInstancesResponseType#convert(Object) is called twice. The first time, as above, the parameter is the expected List<MyResponse>, and again, no conversion is necessary. However, MultipleInstancesResponseType#convert(Object) is then called again, with the parameter being List<LinkedHashMap>. This requires conversion, which fails, because List<MyResponse> can't be converted to List<MyResponse>.

I see both convert calls in my debugger because in my test the same JVM is both making and handling the query.

I believe what is happening is that the query handler is returning the List<MyResponse>and the framework is calling MultipleInstancesResponseType#convert(Object) as per normal. The response is then serialized (gRPC?) and sent to the server, which then sends the response to the original caller. The original caller then tries to convert the payload, and fails. So, somewhere in the gRPC serialization/deserialization process, some type information has been lost.

The net result is that the original caller gets an IllegalArgumentException stating

Retrieved response [class java.util.ArrayList] is not convertible to a List of the expected response type [class MyResponse]

Setting a breakpoint on the GrpcPayloadSerializer shows that the response payload, at the time it's serialized to be sent to the server, is correctly a List<MyResponse>.

The documentation seems to be saying clearly that List<of-something> is a supported query handler return type.


Solution

  • As @ptomli already figured out, this is more of a Jackson issue rather than Axon.

    But to add to that, AxonFramework provided a fix for this on this PR. It is not released yet (I believe it will be part of the 4.4 release) but you can have a look at the solution yourself to write your own workaround or wait for the mentioned release.