You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by "Donatas Ciuksys (JIRA)" <ji...@apache.org> on 2014/10/04 14:55:33 UTC

[jira] [Created] (TOMEE-1379) TransactionSynchronizationRegistry not found in JNDI for EJB Timer started transactions

Donatas Ciuksys created TOMEE-1379:
--------------------------------------

             Summary: TransactionSynchronizationRegistry not found in JNDI for EJB Timer started transactions
                 Key: TOMEE-1379
                 URL: https://issues.apache.org/jira/browse/TOMEE-1379
             Project: TomEE
          Issue Type: Bug
    Affects Versions: 1.7.1
         Environment: TomEE Plus, Windows 7 x64, Oracle JDK 1.7.0_67
            Reporter: Donatas Ciuksys


To reproduce:
1. Create EJB class and JSF page from the source pasted below.
2. Clicking JSF page button "Test EJB business method transaction" gives correct output:
{code}
TEST TIMER BEGIN:
timerFired(): txKey = [Xid:globalId=15000000047544d4944000000000000000000000000000000000000000000000000000,length=64,branchId=0000000000000000000000000000000000000000000000000000000000000000,length=64]
TEST TIMER END
afterCompletion(): txKey = [Xid:globalId=15000000047544d4944000000000000000000000000000000000000000000000000000,length=64,branchId=0000000000000000000000000000000000000000000000000000000000000000,length=64]
{code}

3. Clicking JSF page button "Test EJB timer transaction" shows that in method "afterCompletion()" TransactionSynchronizationRegistry is not found in JNDI:
{code}
TEST TIMER BEGIN:
timerFired(): txKey = [Xid:globalId=e000000047544d4944000000000000000000000000000000000000000000000000000,length=64,branchId=0000000000000000000000000000000000000000000000000000000000000000,length=64]
TEST TIMER END
afterCompletion(): errorMessage = Name [TransactionSynchronizationRegistry] is not bound in this Context. Unable to find [TransactionSynchronizationRegistry].
{code}

WHY I need all this :) I have implemented TransactionScoped CDI context, that listens for afterCompletion() events and destroyes TransactionScoped beans. Well, I have memory leak currently for transactions started by EJB timers...

*Source code*:
JSF:
{code}
            <h:form>
                <h:commandButton value="Test EJB Timer transaction"
                                 actionListener="#{testEjbTimerTx.setTimerNow}"/>
                <h:commandButton value="Test EJB business method transaction"
                                 actionListener="#{testEjbTimerTx.timerFired}"/>
            </h:form>
{code}

EJB class:
{code}
import org.joda.time.LocalTime;

import javax.annotation.Resource;
import javax.ejb.*;
import javax.inject.Named;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.Synchronization;
import javax.transaction.TransactionSynchronizationRegistry;

@Named
@Singleton
public class TestEjbTimerTx {

    @Resource
    private TimerService timerService;

    public static final String TRANSACTION_SYNCHRONIZATION_REGISTRY_JNDI_NAME = "java:comp/TransactionSynchronizationRegistry";

    @Timeout
    public void timerFired() {
        System.out.println("TEST TIMER BEGIN:");
        try {
            TransactionSynchronizationRegistry txRegistry = (TransactionSynchronizationRegistry) new InitialContext().lookup(
                    TRANSACTION_SYNCHRONIZATION_REGISTRY_JNDI_NAME
            );
            System.out.println("timerFired(): txKey = " + txRegistry.getTransactionKey());
            txRegistry.registerInterposedSynchronization(new TxListener());
        } catch (NamingException e) {
            System.out.println("timerFired(): errorMessage = " + e.getMessage());
        }
        System.out.println("TEST TIMER END");
    }

    public void setTimerNow() {
        LocalTime localTime = new LocalTime().plusSeconds(3);
        ScheduleExpression schedule = new ScheduleExpression().second(localTime.getSecondOfMinute())
                .minute(localTime.getMinuteOfHour()).hour(localTime.getHourOfDay());

        TimerConfig timerConfig = new TimerConfig();
        timerConfig.setPersistent(false);

        timerService.createCalendarTimer(schedule, timerConfig);
    }

    public static class TxListener implements Synchronization {
        @Override
        public void beforeCompletion() {}

        @Override
        public void afterCompletion(int i) {
            try {
                TransactionSynchronizationRegistry txRegistry = (TransactionSynchronizationRegistry) new InitialContext().lookup(
                        TRANSACTION_SYNCHRONIZATION_REGISTRY_JNDI_NAME
                );
                System.out.println("afterCompletion(): txKey = " + txRegistry.getTransactionKey());
            } catch (NamingException e) {
                System.out.println("afterCompletion(): errorMessage = " + e.getMessage());
            }
        }
    }
}
{code}




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)