Command resulted in com.thoughtworks.xstream.converters.ConversionException(Failed calling method) when using spring cloud connector for distributed command bus

I get the below-mentioned exception thrown from saga event handler. I have configured distributed command bus using spring cloud connector, and whenever a command is dispatched from saga event handler using the command gateway this exception id thrown.

Command ‘com.metamagic.ms.commands.PlaceOrderCommand’ resulted in com.thoughtworks.xstream.converters.ConversionException(Failed calling method
---- Debugging information ----
message : Failed calling method
cause-exception : com.thoughtworks.xstream.converters.ConversionException
cause-message : Failed calling method
method : java.util.concurrent.CopyOnWriteArrayList.writeObject()
-------------------------------)

My saga event handler code snippet.

@StartSaga
@SagaEventHandler(associationProperty = “userId”)
public void handle(Event event) {

// business logic
commandGateway
.send(new Command(arguments));
}

Any help will be appreciated.

Hi Ashutosh,

This ‘conversion exception’ only occurs when the PlaceOrderCommand is published from a Saga?
Thus, you’ve got a use case were the PlaceOrderCommand is published from a non-event-handling-component (I regard a Saga as an Event Handling Component as it’s triggered by events) which does work?

And just to be clear, this exception is thrown on the sending side of that command, not on the receiving side, correct?

Could you share a more elaborate stack trace of the exception you’re getting?
Maybe that contains some info which I can help you out with, since with the current snippets you’ve shared I’m kinda at a loss.

My general knowledge of XStream is that it is very good at serializing about everything, so I’m kinda surprised you’ve got this exception.

Let’s try to figure this out; interested what the problem is here!

Cheers,

Steven

Actually, PlaceOrderCommand is published from non-event-handling component and not from saga event handler. And PlaceOrderCommand results in OrderPlacedEvent from ShoppingCart aggregate.

My saga code.

@StartSaga
@SagaEventHandler(associationProperty = “userId”)
public void handle(OrderPlacedEvent orderPlacedEvent) {
String orderId = UUID.randomUUID().toString();
associateWith(“orderId”, orderId);
Set lineItemDTOs = null;
if (orderPlacedEvent.getItems() != null) {
lineItemDTOs = orderPlacedEvent.getItems().stream().map(
items -> new LineItemDTO(items.getItemId(), items.getName(), items.getQuantity(), items.getPrice()))
.collect(Collectors.toSet());
}
commandGateway
.send(new CreateOrderCommand(orderId, orderPlacedEvent.getCartId(), orderPlacedEvent.getUserId(), lineItemDTOs));
}

Hi Ashutosh,

Cant see something wrong in that Saga Event Handler on face value.

If you could still provide a stack trace of the exception your getting, maybe that might shed some light on the issue at hand.

Cheers,

Steven

o.a.c.gateway.DefaultCommandGateway : Command ‘com.metamagic.ms.commands.PlaceOrderCommand’ resulted in com.thoughtworks.xstream.converters.ConversionException(Failed calling method
---- Debugging information ----
message : Failed calling method
cause-exception : com.thoughtworks.xstream.converters.ConversionException
cause-message : Failed calling method
method : sun.net.www.http.KeepAliveCache.writeObject()
-------------------------------)

I Don’t get anything more than this as a warning.

Hi Ashutosh,

Weird, would’ve expected you’d receive more.
A quick google on the ConversionException you’re receiving however does not give any concrete answers to what is going wrong here…

I’d assume though this issue has nothing to do with using the DistributedCommandBus or the Spring Cloud CommandBusConnector/CommandRouter for that matter…

As I suggested in my first response, it might be a good idea to confirm that, by checking if you get the same warning if you publish the PlaceOrderCommand on a CommandBus implementation which does not publish to another node.

I’d however rather say this lies with XStream and how your PlaceOrderCommand is modeled.

What does your PlaceOrderCommand look like, implementation wise?

And one other thing, are your Axon nodes homogeneous or heterogeneous?

Let’s figure this out!

Cheers,

Steven

Thanks Steven.

This problem could not be related to DistributedCommandBus or the Spring Cloud CommandBusConnector/CommandRouter.

I will test the code with SimpleCommandBus and let you know what happened.

And PlaceOrderCommand is an immutable class with two final data members and nothing much. Axon nodes are heterogeneous.

Hi,

the error shows that XStream is complaining about an HTTP Cache related object. That indicates the class references something that you probably didn’t intend to.
You said the class only references two objects. Is that class perhaps a non-static inner class? Or are you using some (annotation based) enhancers like Lombok? In that case, you might be implicitly referencing other classes as well.

By the way, your first exception showed a different error, where it complained about a concurrent collection. Which fields do you expect your object to contain?

Cheers,

Allard

Hello all,

Is there any updates on this? Just got the same result.
and puzzled what’s the problem is.

在 2018年4月20日星期五 UTC+8下午10:28:16,ashutos…@metamagic.in写道:

It’s most likely because the message or metadata contains information that XStream cannot (de)serialize. There is probably a detailed stacktrace somewhere indicating where the problem is.

Probably because the commandGateway field declaration isn’t transient.

Hi all,

I’m facing the same issue, but the logs dont show any useful information (at least for me).
Attached the stacktrace. Do you have any idea?

It happens when sending a new command within a saga.

error_axon.log (46.1 KB)

Seems like XStream cannot serialize something.
The only ‘known issue’ with XStream related exceptions is when you have a Saga with a field that contains an infrastructure component which is not declared transient.
Note that the SagaTestFixture checks this.

Argh, you’re right … the CommandGateway wasn’t marked as transient. Thanks for the hint …

hi @Allard

I am using Axon4.2 with Spring boot. Created simple saga. Its works well during Application running. However once it restarts, it re-runs the Saga again.

So Tried to use MongoSagaStore for persisting SgagStore, did not work. Below are code snippet. Please help.

@Configuration
public class AxonConfig {

  @Bean
  @Primary
  public Serializer serializer() {
    final XStream xStream = new XStream(new CompactDriver());
    xStream.setClassLoader(this.getClass().getClassLoader());
    return XStreamSerializer.builder().xStream(xStream).build();
  }
  @Bean
  public MongoSagaStore sagaStore(MongoClient client) {
    MongoSagaStore.Builder builder = new MongoSagaStore.Builder();
    builder.mongoTemplate(DefaultMongoTemplate.builder()
            .mongoDatabase(client).build());
    return builder.build();
  }

MySagaClass

i modified MongoSagaStore. below is the code snipped and it worked for me.
we need use builder.serializer(JacksonSerializer.defaultSerializer()); then we wont get that exception.

@bean
public SagaStore sagaRepository(MongoClient mongoClient) {
MongoSagaStore.Builder builder = new MongoSagaStore.Builder();
builder.mongoTemplate(DefaultMongoTemplate.builder()
.mongoDatabase(mongoClient).build());
builder.serializer(JacksonSerializer.defaultSerializer());
return builder.build();
}

thanks

Hi Siddalinga,

the problem with the Saga getting the events again is probably the cause of the TokenStore being used. Axon defaults to Tracking Processing, and if it can’t find any location to store the tokens in, it uses an InMemoryTokenStore. Try configuring a TokenStore implementation in your application context.

Hope this helps.
Cheers,