1 Reply Latest reply on Apr 18, 2018 5:29 AM by mkouba

    Implementing a TransactionServices for Java SE - question about AfterCompletion

    steappe

      I'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?