javatransactionsjboss7.xejb-3.0wildfly-9

EJB with CMT when migrate from JBoss 7 to WildFly 9


I'm migrating my application from JBoss 7 to WildFly (v9.0.1) and it is not deployed because of bean transaction management error.

    Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup env/com.component.eventmgt.EventServiceImpl/transaction [Root exception is java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:157)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 90 more
Caused by: java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:319)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)
    ... 95 more
Caused by: javax.naming.NameNotFoundException: UserTransaction [Root exception is java.lang.IllegalStateException: WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:153)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 96 more

Here is the EventServiceImpl class.

    @Stateless
    @Remote(EventService.class)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public class EventServiceImpl implements EventService {

        /**
         * Logger
         */
        private static Logger log = LoggerFactory.getLogger(EventService.class);

        private EventTableDAO eventDao;

        @PersistenceContext(unitName = "SOMF-GT")
        private EntityManager entityManager;

        @Resource
        private UserTransaction transaction;

       public List<Map> loadEvents() throws EventsException {

        Configuration configurationEntry = new Configuration();
        try {
            Map configuration = configurationService.getConfiguration();
            if (configuration != null) {

        eventDao = new EventTableDAO(Event.class, entityManager, transaction);
        List<Map> eventsMapList = new ArrayList();
}
}

I know that if i changed the transaction management to BMT with @TransactionManagement(TransactionManagementType.BEAN) but then the following error emerge

WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)

I want to know why we have to change this in the first place ?

Any information, please !


Solution

  • These changes rolled out in Wildfly 8 and were (as noted below) based on standardization of the global JNDI namespace in EJB 3.1.

    From the Wildfly 8 Developer Guide:

    EJB 3.1 introduced a standardized global JNDI namespace and a series of related namespaces that map to the various scopes of a Java EE application. The three JNDI namespaces used for portable JNDI lookups are java:global, java:module, and java:app. If you use JNDI lookups in your application, you will need to change them to follow the new standardized JNDI namespace convention.

    To conform to the new portable JNDI namespace rules, you will need to review the JNDI namespace rules and modify the application code to follow these rules.

    The guide further notes:

    WildFly 8 has tightened up on JNDI namespace names to provide predictable and consistent rules for every name bound in the application server and to prevent future compatibility issues. This means you might run into issues with the current namespaces in your application if they don't follow the new rules.

    Here's a snippet from the table showing Examples of JNDI mappings in previous releases and how they might look now specific to the UserTransaction:

    Previous Namespace          New Namespaces
    ------------------          --------------
    java:comp/UserTransaction   java:comp/UserTransaction (This will not be accessible for non EE threads, e.g. Threads your application directly creates)
    java:comp/UserTransaction   java:jboss/UserTransaction (Globally accessible, use this if java:comp/UserTransaction is not available)
    

    Edit re: WFLYEJB0137:

    This is theory-craft and may be worthless - let me know and I'll delete it. Java EE 6 Tutorial - Container-Managed Transactions says:

    Enterprise beans that use container-managed transaction demarcation also must not use the javax.transaction.UserTransaction interface.

    Further:

    (Transaction) Required Attribute

    If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.

    The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later.

    The exception message pretty much says it all:

    WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction

    Your EJB is using container managed transaction (CMT) demarcation which does not inter-operate with bean managed transaction (BMT) demarcation wherein UserTransaction lies.

    Regarding a switch to BMT and

    WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)

    I found Transaction is required to perform this operation (either use a transaction or extended persistence context) which seems to indicate that the transaction is to be managed by you, as you noted in your comments @Marco. It appears that you have made the appropriate modification.