How to get the UserTransaction reference on the Client side in EAP 6

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 6.x

Issue

  • How to get the UserTransaction reference on the Client side in EAP6 ?
  • Is it possible to get a UserTransaction reference for a standalone client?

Resolution

If the client application is running in JBoss EAP, then see Client application running in JBoss Server, if the client application is a standalone java application see Client application running in a Standalone Java Client

Client application running in JBoss Server

  • On the JBoss Server side the lookup can be performed on the following JNDI names:

"java:comp/UserTransaction" - This will not be accessible for non EE threads, e.g. Threads your application directly creates or by non EE components.
"java:jboss/UserTransaction" - Globally accessible, use this if java:comp/UserTransaction is not available.

  • You can also use @Resource annotation to inject it on your EJBs as following:
import javax.transaction.UserTransaction;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

@TransactionManagement(TransactionManagementType.BEAN)
@Stateless  
@Remote(TestRemote.class)
public class TestBean implements TestRemote
 {
     @Resource UserTransaction tx;
     public String testing(String name)
	    {
                    try {
                           System.out.println("Got the tx = "+tx);
                           System.out.println("UserTransaction = "+tx.getStatus());   //    6 means no TX
                           tx.begin();
                           System.out.println("UserTransaction = "+tx.getStatus());   // 0 means active
                           /*
                            STATUS_ACTIVE               0
                            STATUS_COMMITTED            3
                            STATUS_COMMITTING           8
                            STATUS_MARKED_ROLLBACK      1
                            STATUS_NO_TRANSACTION       6
                            STATUS_PREPARED             2
                            STATUS_PREPARING            7
                            STATUS_ROLLEDBACK           4
                            STATUS_ROLLING_BACK         9
                            STATUS_UNKNOWN              5
                            */

Client application running in a Standalone Java Client

import org.jboss.ejb.client.EJBClient;
import javax.transaction.UserTransaction;
.
.
    Context context=null;
    UserTransaction tx=null;
    try {
      Properties props = new Properties();
      // REMEMBER: there must be a jboss-ejb-client.properties with the connection parameter
      //           in the clients classpath
      props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
      context = new InitialContext(props);	
      System.out.println("\n\tGot initial Context: "+context);
      tx=EJBClient.getUserTransaction("yourServerName");
      System.out.println("UserTransaction = "+tx.getStatus());
      tx.begin();
      // do some work
      ...
    }catch (Exception e) {
      e.printStackTrace();
      tx.rollback();
    }finally{
      if(context != null) {
        context.close();
      }
    }

NOTE:
If you want to get the UserTransaction on the client side then start your server with the following system property "-Djboss.node.name=yourServerName" then use it on client side as following:

tx=EJBClient.getUserTransaction("yourServerName");

At the moment there is an open RFE (PRODMGT-473) to enhance the standalone client so that it is possible to get a UserTransaction reference without knowledge of the server side environment.

Important:

  • Use of the EJBClient is only possible if the ejb.client is used, this means the use of the jboss-ejb-client.properties as shown above or direct use of the EJBClientContext API and set all programatically.
  • It is not possible if remote-naming is used, this is the case if the Context.PROVIDER_URL starts with remote://. The issue is that the InitialContext creates its own EJBClient instance which can not be accessed with the static EJBClient.getUserTransaction() method. The static getUserTransaction() will return a transaction from the default client context which might not be initialized. Under some special circumstances it might be possible that a UserTransaction is returned but this can not be expected!
  • Together with the scoped-context (introduced in EAP6.1) it is not possible at the moment as the EJBClient.getUserTransaction(...) is using the default context instead of the scoped one which may cause unexpected behaviour. But this is a known issue and might resolved soon

Related Solutions

EJBCLIENT000045: User transactions not supported by this context in JBoss EAP 6.4
How to get the UserTransaction reference on the Client side in EAP 5 / 4

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.