AxonFramework + OSGi + JPA EventStore

430 views
Skip to first unread message

lb

unread,
May 15, 2013, 8:47:16 AM5/15/13
to axonfr...@googlegroups.com
Hi,
I'm working to integrate Axon in some OSGi/Apache-Karaf examples (https://github.com/lburgazzoli/lb-karaf-examples):
- axon-data
- axon-engine
- axon-event-listener

The first thing I've noticed is that the axon-core jar is not OSGi ready so in Apache Karaf I've installed it trough Karaf's bundle wrap functionality:

karaf@kha-1> install -s wrap:mvn:org.axonframework/axon-core/2.0
Bundle ID: 687

karaf@kha-1> la | grep axon
[ 687] [Active     ] [            ] [   80] wrap_mvn_org.axonframework_axon-core_2.0 (0)

Is there any plan to build an OSGi friendly distribution ?


Then when a dummy CreateDataCommand is sent to the framework. OpenJPA raises the following exception and roll-back:

2013-05-15 13:34:55,197|WARN |org.apache.openjpa                              |org.apache.openjpa.lib.log.SLF4JLogFactory$LogAdapter            > Found no persistent property in "org.axonframework.eventstore.jpa.DomainEventEntry"
2013-05-15 13:34:55,217|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.NestableUnitOfWork                  > An error occurred while committing this UnitOfWork. Performing rollback...
2013-05-15 13:34:55,217|DEBUG|org.springframework.transaction                 |framework.transaction.support.AbstractPlatformTransactionManager > Initiating transaction rollback
2013-05-15 13:34:55,217|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.UnitOfWorkListenerCollection        > Notifying listeners of rollback
2013-05-15 13:34:55,217|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.UnitOfWorkListenerCollection        > Notifying listener [org.axonframework.repository.LockingRepository$LockCleaningListener] of rollback
2013-05-15 13:34:55,218|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.NestableUnitOfWork                  > Stopping Unit Of Work
2013-05-15 13:34:55,218|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.UnitOfWorkListenerCollection        > Notifying listeners of cleanup
2013-05-15 13:34:55,218|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.UnitOfWorkListenerCollection        > Notifying listener [org.axonframework.repository.LockingRepository$LockCleaningListener] of cleanup
2013-05-15 13:34:55,218|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.UnitOfWorkListenerCollection        > Listeners successfully notified
2013-05-15 13:34:55,218|DEBUG|wrap_mvn_org.axonframework_axon-core_2.0        |org.axonframework.unitofwork.NestableUnitOfWork                  > Clearing resources of this Unit Of Work.
2013-05-15 13:34:55,218|DEBUG|axon-engine                                     |m.github.lburgazzoli.examples.karaf.axon.cmd.CreateDataCommand$1 > onFailure => <org.apache.openjpa.persistence.ArgumentException>
2013-05-15 13:34:55,218|DEBUG|axon-engine                                     |m.github.lburgazzoli.examples.karaf.axon.cmd.CreateDataCommand$1 > onFailure
<openjpa-2.2.2-r422266:1468616 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: You have specified Table annotation or XML descriptor element for MappedSuperclass "org.axonframework.eventstore.jpa.AbstractEventEntry". A class designated as a mapped superclass can not have a separate table defined for it.      
        at org.apache.openjpa.persistence.jdbc.AnnotationPersistenceMappingParser.parseTable(AnnotationPersistenceMappingParser.java:530)
        at org.apache.openjpa.persistence.jdbc.AnnotationPersistenceMappingParser.parseClassMappingAnnotations(AnnotationPersistenceMappingParser.java:350)
        at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parseClassAnnotations(AnnotationPersistenceMetaDataParser.java:697)
        at org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parse(AnnotationPersistenceMetaDataParser.java:415)
        at org.apache.openjpa.persistence.PersistenceMetaDataFactory.load(PersistenceMetaDataFactory.java:260)
        at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:586)
        at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:396)
        at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:388)
        at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:693)
        at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:649)
        at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:417)
        at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:388)
        at org.apache.openjpa.jdbc.meta.MappingRepository.getMapping(MappingRepository.java:354)
        at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:682)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.jdbc.meta.MappingTool.buildSchema(MappingTool.java:754)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:652)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:154)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:164)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:122)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:209)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)[755:org.apache.openjpa:2.2.2]
        at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60)[755:org.apache.openjpa:2.2.2]
        at org.apache.aries.jpa.container.impl.CountingEntityManagerFactory.createEntityManager(CountingEntityManagerFactory.java:71)[59:org.apache.aries.jpa.container:1.0.0]
        at org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry.getCurrentPersistenceContext(JTAPersistenceContextRegistry.java:152)[60:org.apache.aries.jpa.container.context:1.0.1]
        at org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager.getPersistenceContext(JTAEntityManager.java:84)[60:org.apache.aries.jpa.container.context:1.0.1]
        at org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager.persist(JTAEntityManager.java:278)[60:org.apache.aries.jpa.container.context:1.0.1]
        at org.axonframework.eventstore.jpa.DefaultEventEntryStore.persistEvent(DefaultEventEntryStore.java:50)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.eventstore.jpa.JpaEventStore.appendEvents(JpaEventStore.java:152)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.eventsourcing.EventSourcingRepository.doSaveWithLock(EventSourcingRepository.java:119)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.eventsourcing.EventSourcingRepository.doSaveWithLock(EventSourcingRepository.java:53)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.repository.LockingRepository.doSave(LockingRepository.java:126)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.repository.AbstractRepository$SimpleSaveAggregateCallback.save(AbstractRepository.java:167)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.unitofwork.DefaultUnitOfWork$AggregateEntry.saveAggregate(DefaultUnitOfWork.java:312)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.unitofwork.DefaultUnitOfWork.saveAggregates(DefaultUnitOfWork.java:277)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.unitofwork.NestableUnitOfWork.commit(NestableUnitOfWork.java:48)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:137)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:103)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:75)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:69)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:85)[687:wrap_mvn_org.axonframework_axon-core_2.0:0]
        at com.github.lburgazzoli.examples.karaf.axon.SimpleAxonEngine.send(SimpleAxonEngine.java:179)[754:axon-engine:1.0.0.SNAPSHOT]
        at com.github.lburgazzoli.examples.karaf.axon.cmd.CreateDataCommand.doExecute(CreateDataCommand.java:42)[754:axon-engine:1.0.0.SNAPSHOT]
        at org.apache.karaf.shell.console.OsgiCommandSupport.execute(OsgiCommandSupport.java:38)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.commands.basic.AbstractCommand.execute(AbstractCommand.java:35)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:78)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:474)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:400)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:89)[14:org.apache.karaf.shell.console:2.3.0]
        at org.apache.karaf.shell.console.jline.Console.run(Console.java:175)[14:org.apache.karaf.shell.console:2.3.0]
        at java.lang.Thread.run(Thread.java:722)[:1.7.0_21]

Is there any way to tell the framework that the exception org.apache.openjpa.persistence.ArgumentException is not fatal?

thx - luca


Allard Buijze

unread,
May 16, 2013, 3:45:47 AM5/16/13
to Axon Framework Users
Hi Luca,

direct OSGi support has been crossing my mind, but hasn't found it's place on the concrete roadmap yet. Some OSGi related issues have been reported (related to ServiceLoader). I am planning to find a solution, to make it work in OSGi environments. Adding the necessary manifest entries to make the axon-core jar an OSGi bundle shouldn't be too hard, but I don't know if that's enough. As you mentioned, bundle wrapping is pretty simple to do.

It seems that OpenJPA doesn't allow the @Table annotation on an @MappedSupperclass. I checked the specification, but I couldn't find anything about this.
Yes, you can indicate that the ArgumentException should not rollback the UnitOfWork. In the SimpleCommandBus, you can configure a RollbackConfiguration. By default, it rolls back on runtime exceptions only. By providing your own implementation, you can tell it to commit on ArgumentException.
Are you sure everything is properly persisted, even though the exception is raised?

Cheers,

Allard





--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

lb

unread,
May 16, 2013, 4:12:40 AM5/16/13
to axonfr...@googlegroups.com
Hi Allard,

I've configured the SimpleCommandBus to use my own RollbackConfiguration (configuration done through OSGi Blueprint) :

    <bean id    = "AXON_CMD_BUS_ROLLBACK_CFG"
          class = "com.github.lburgazzoli.examples.karaf.axon.SimpleRollbackConfiguration">
    </bean>

    <bean id    = "AXON_CMD_BUS_TX_MANAGER"
          class = "com.github.lburgazzoli.examples.karaf.axon.SimpleTransactionManager">
        <argument ref="osgiJtaTransactionManager"/>
    </bean>

    <bean id    = "AXON_CMD_BUS"
          class = "org.axonframework.commandhandling.SimpleCommandBus">
        <property name="rollbackConfiguration" ref="AXON_CMD_BUS_ROLLBACK_CFG"/>
        <property name="transactionManager"    ref="AXON_CMD_BUS_TX_MANAGER"/>
    </bean>

The SimpleRollbackConfiguration class is really really dummy:

    public class SimpleRollbackConfiguration implements RollbackConfiguration {
        private static final Logger LOGGER = LoggerFactory.getLogger(SimpleRollbackConfiguration.class);

        @Override
        public boolean rollBackOn(Throwable throwable) {
            LOGGER.warn("<<<< rollBackOn >>>>",throwable);
            return !(throwable instanceof Exception) || throwable instanceof RuntimeException;
        }
    }

It looks like that the method rollBackOn is never invoked. 
Btw, I've tested it on hibernate-osgi and it seems to work (still have something to fix/understand but basic tests look good).


About the remaining OSGi stuffs: is there an open issue related to ServiceLoader? apache-camel osgi budle does something related to ServiceLoader and we may use it as reference.


--
You received this message because you are subscribed to a topic in the Google Groups "Axon Framework Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/axonframework/nV_dpLrBD68/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to axonframewor...@googlegroups.com.

Allard Buijze

unread,
May 16, 2013, 4:27:46 AM5/16/13
to Axon Framework Users
Hi Luca,

my bad. The rollbackOn method is only invoked for exceptions caused by the domain logic. In this case, the exception is caused by the "commit" of the UnitOfWork. It looks like I need to move the @Table annotations from the mapped superclass to the entities to make it work in OpenJpa.

I didn't create issues for the OSGi related work yet. I will break it down to sensible items and create the issues soon.

Cheers,

Allard

lb

unread,
May 16, 2013, 8:27:14 AM5/16/13
to axonfr...@googlegroups.com
I've sent a pull request https://github.com/AxonFramework/AxonFramework/pull/89 to make axon-core OSGi compliant.
Do you have any info about the issues with ServiceLoader? I may have a look at it as soon as I have a little time :-)

Allard Buijze

unread,
May 16, 2013, 9:22:15 AM5/16/13
to Axon Framework Users
Hi Luca,

thanks for the pull request. I will look at it shortly.

The issues were discussed on the mailinglist: https://groups.google.com/forum/?fromgroups=#!topic/axonframework/1fgnW0CNUcQ. Check the message by Ivica Munitic, who describes the problems encountered.

Cheers,

Allard
Reply all
Reply to author
Forward
0 new messages