Breaking change

80 views
Skip to first unread message

Sebastian Ganslandt

unread,
Oct 10, 2012, 6:58:00 AM10/10/12
to axonfr...@googlegroups.com
Hi Allard,

It seems your latest snapshot build introduced something not quite backward compatible. Our saga event handlers currently throws the following exception when handling events:

2012-10-10 12:52:19,289 [SimpleAsyncTaskExecutor-1] ERROR com.casumo.platform.event.infrastructure.BackOffErrorHandler  - Error when handling event
org.springframework.amqp.rabbit.listener.ListenerExecutionFailedException: Listener threw exception
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:590)
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:529)
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:472)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:56)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:103)
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:560)
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:452)
---- Debugging information ----
field               : default
class               : org.axonframework.saga.annotation.AssociationValuesImpl
required-type       : org.axonframework.saga.annotation.AssociationValuesImpl
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /com.casumo.platform.components.bonus.command.sagas.DepositBonusSaga/associationValues/org.axonframework.saga.annotation.AssociationValuesImpl/default
line number         : 1
class[1]            : com.casumo.platform.components.bonus.command.sagas.DepositBonusSaga
version             : null
-------------------------------
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.determineType(AbstractReflectionConverter.java:453)
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:294)
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234)
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:322)
        at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234)
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
        at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
        at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)

We have not yet dug down in the problem except for testing to downgrade xstream to 1.4.2 again, which didn't help. Do you have any clue what could have caused this?

Best Regards
Sebastian

Allard Buijze

unread,
Oct 10, 2012, 7:49:50 AM10/10/12
to axonfr...@googlegroups.com
Hi Sebastian,

I made some changes to the implementation of the AssociationValuesImpl class. I didn't expect them to be backwards incompatible, but it seems they are.
The previous version of the class used some Java Serialization API methods (readObject and writeObject), but didn't really do special things in them, other than initialization of some transient fields. XStream adds a default element to the serialized output to tell the deserializer that a "input.defaultReadObject" will be invoked.
In the new version, this element is not necessary anymore. A quick fix could be to remove the <default/> element from the "org.axonframework.saga.annotation.AssociationValuesImpl" element in your serialized Sagas.

If you have no clue what I mean, send me a serialized Saga instance. I can then mark the components that need to be removed.

Cheers,

Allard

Allard Buijze

unread,
Oct 10, 2012, 8:11:36 AM10/10/12
to axonfr...@googlegroups.com
I realized that I still had old and new style serialized Sagas in my local database. Here is the old format:
<bb.sagas.tournament.TournamentScheduleSaga>
    <associationValues class="org.axonframework.saga.annotation.AssociationValuesImpl" serialization="custom">
        <org.axonframework.saga.annotation.AssociationValuesImpl>
            <default>
                <values>... removed content...

And this is the new format:
<bb.sagas.tournament.TournamentScheduleSaga>
    <associationValues class="org.axonframework.saga.annotation.AssociationValuesImpl">
        <values>

As you can see, two levels of elements have been removed, as well as the serialization="custom" attribute.

Cheers,

Allard

Sebastian Ganslandt

unread,
Oct 10, 2012, 8:12:28 AM10/10/12
to axonfr...@googlegroups.com
I have a clue what you mean and there seems to be a few other differences as well. Below is an example of one of our serialized sagas together with an xstream serialized saga from the new version. Changes marked in red (newlines added for readability).

As I see it a simple search and replace removing the marked stuff. Would you agree? Can you see any other problems? 

<com.casumo.platform.components.bonus.command.sagas.DepositBonusSaga>
<associationValues class="org.axonframework.saga.annotation.AssociationValuesImpl" serialization="custom">
<org.axonframework.saga.annotation.AssociationValuesImpl>
<default>
<values class="sorted-set">
<comparator class="org.axonframework.saga.annotation.AssociationValuesImpl$AssociationValueComparator"/>
<org.axonframework.saga.AssociationValue><propertyKey>playerId</propertyKey><propertyValue>XXX</propertyValue></org.axonframework.saga.AssociationValue>
<org.axonframework.saga.AssociationValue><propertyKey>sagaIdentifier</propertyKey><propertyValue>XXX</propertyValue></org.axonframework.saga.AssociationValue>
</values>
</default>
</org.axonframework.saga.annotation.AssociationValuesImpl>
</associationValues>
<identifier>XXX</identifier><isActive>false</isActive><allDepositBonusBadgeIds/></com.casumo.platform.components.bonus.command.sagas.DepositBonusSaga>

<org.axonframework.saga.annotation.AbstractAnnotatedSagaTest_-StubAnnotatedSaga>
<associationValues class="org.axonframework.saga.annotation.AssociationValuesImpl">
<values>
<org.axonframework.saga.AssociationValue><propertyKey>sagaIdentifier</propertyKey><propertyValue>425b8d90-12d0-11e2-8a38-002618f2e896</propertyValue></org.axonframework.saga.AssociationValue>
</values>
</associationValues>
<identifier>425b8d90-12d0-11e2-8a38-002618f2e896</identifier><isActive>true</isActive><invocationCount>0</invocationCount></org.axonframework.saga.annotation.AbstractAnnotatedSagaTest_-StubAnnotatedSaga>

Allard Buijze

unread,
Oct 10, 2012, 8:22:16 AM10/10/12
to axonfr...@googlegroups.com
Looks like removing the red stuff will get you back on the road.
Sorry for pushing incompatible changes down your throat. Good news it that the new code performs much better.

Allard

Sebastian Ganslandt

unread,
Oct 10, 2012, 8:25:37 AM10/10/12
to axonfr...@googlegroups.com
: )

Sebastian Ganslandt

unread,
Oct 11, 2012, 1:25:59 AM10/11/12
to axonfr...@googlegroups.com
Once again we are back on the latest snapshot build of axon in production : ). 

For any one else interested, this script did the trick for us (MySQL)

use casumo_command;

create table SagaEntry2 like SagaEntry;
insert SagaEntry2 select * from SagaEntry;

update SagaEntry2 set serializedSaga = replace(serializedSaga, ' serialization="custom"', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, '<org.axonframework.saga.annotation.AssociationValuesImpl>', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, '<default>', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, ' class="sorted-set"', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, '<comparator class="org.axonframework.saga.annotation.AssociationValuesImpl$AssociationValueComparator"/>', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, '</default>', '');
update SagaEntry2 set serializedSaga = replace(serializedSaga, '</org.axonframework.saga.annotation.AssociationValuesImpl>', '');

rename table SagaEntry to SagaEntry_old;
rename table SagaEntry2 to SagaEntry;

Cheers
Sebastian

Sebastian Ganslandt

unread,
Oct 11, 2012, 1:28:22 AM10/11/12
to axonfr...@googlegroups.com
You should probably check that none of the replaced terns are part of your actual saga instances as well...
Reply all
Reply to author
Forward
0 new messages