Implementing a TransactionServices for Java SE - question about AfterCompletion
steappe Apr 12, 2018 1:21 PMI'm currently implementing a solution to leverage the transactional event facilities of CDI in Java SE.
I've implemented:
- A TransactionServices class and made sure it's loaded via the ServiceLoader
- A UserTransaction class
- A Transactional interceptor
And I have added the weld-jta module to my project.
Everything is fine until I invoke afterCompletion() of the synchronization observer.
Test conditions:
I have one method that fires an event:
@Transactional
private void onInit(@Observes @Initialized(ApplicationScoped.class) Object event) {
LOGGER.info("firing event");
events.fire("hello");
LOGGER.info("event fired");
}
And I have an observer method that is transactional:
@Transactional
private void onEvent(@Observes(during = TransactionPhase.AFTER_SUCCESS) String event) {
LOGGER.info(() -> String.format("event received after success: %s", event));
}
When afterCompletion is invoked, the transaction related to 'onInit' is committed. A new transaction is started when the observer method is invoked.
When the observer method returns, the later transaction (related to 'onEvent' is committed). But then, a new event is fired again and it's value is null, and in the logs I can see:
InfraUserTransaction - begin new transaction
TransactionTest - firing event
TransactionTest - event fired
InfraUserTransaction - committing transaction
InfraUserTransaction - transaction committed
InfraUserTransaction - notifying after completion - STATUS_COMMITTED
InfraUserTransaction - begin new transaction
TransactionTest - event received after success: hello
InfraUserTransaction - committing transaction
InfraUserTransaction - transaction committed
InfraUserTransaction - notifying after completion - STATUS_COMMITTED
ERROR Event - WELD-000401: Failure while notifying an observer [BackedAnnotatedMethod] private steappe.production.application.TransactionTest.onEvent(@Observes String) of event null.
java.lang.IllegalAccessError: tried to access method steappe.production.application.TransactionTest.onEvent(Ljava/lang/String;)V from class steappe.production.application.TransactionTest$Proxy$_$$_WeldSubclass
InfraUserTransaction - after completion notified
InfraUserTransaction - after completion notified
As you can see, the list of events to distribute after the completion of the first commit seems to contain some remaining of the first distributed event. Then, after the second commit, WELD tries to distribute this event again.
Did I do something wrong? Or is there a bug in WELD?