1 2 Previous Next 20 Replies Latest reply on Jan 9, 2014 11:28 AM by vasilievip

    Bootstrap JTA in unit test

    vasilievip

      Hello,

       

      I'm trying to figure out how to plug real transaction manager inside of unit test which runs with CDI injection but w/o any arquillian.

      Could someone point me into right example on how to get this done?

       

      Here is an example of CDI+JPA only unit test which I like to get enhanced with standard "Transactional" annotation instead of custom one:

      http://os890.blogspot.com/2013/12/add-on-cdi-tests-with-deltaspike-05.html

       

      Thanks

        • 1. Re: Bootstrap JTA in unit test
          tomjenkinson

          Hi,

           

          There is a simple quickstart over here that uses a transaction manager:

          https://github.com/jbosstm/quickstart/tree/master/ArjunaJTA/maven

           

          Its not a unit test but it should be possible to extrapolate it out quite easily and might be clearer to see the minimal steps you need to perform to launch a transaction manager.

           

          Hope it helps,

          Tom

           

          EDIT:

          This one is quite useful too: quickstart/ArjunaJTA/javax_transaction/

           

          Take a look through our entire library over here: quickstart/

          1 of 1 people found this helpful
          • 2. Re: Bootstrap JTA in unit test
            vasilievip

            Let me look into. Thanks!

            • 3. Re: Re: Bootstrap JTA in unit test
              vasilievip

              Tom Jenkinson wrote:

               

              Hope it helps,

              Tom

              It doesn't, sorry. I've looked over examples and I do not see how can I plug this into weld.

              I've looked, for example, into bitronix and it was quite easy to get into: http://docs.codehaus.org/display/BTM/Jndi2x

              I have bitronix plugged to weld, but they do not provide JTA 1.2 feature I need - @Transactional annotation and listeners to handle it.

               

              import bitronix.tm.TransactionManagerServices;
              import org.jboss.weld.transaction.spi.TransactionServices;
              
              
              import javax.naming.Context;
              import javax.naming.InitialContext;
              import javax.naming.NamingException;
              import javax.transaction.Status;
              import javax.transaction.Synchronization;
              import javax.transaction.TransactionSynchronizationRegistry;
              import javax.transaction.UserTransaction;
              import java.util.Hashtable;
              
              
              public class BitronixTransactionServicesImpl implements TransactionServices {
              
              
                  static  Context ctx;
                  static {
                      Hashtable env = new Hashtable();
                      env.put(Context.INITIAL_CONTEXT_FACTORY, "bitronix.tm.jndi.BitronixInitialContextFactory");
                      try {
                          ctx = new InitialContext(env);
                          ctx.lookup(TransactionManagerServices.getConfiguration().getJndiUserTransactionName());
                      } catch (NamingException e) {
                          e.printStackTrace();
                      }
                  }
                  @Override
                  public void registerSynchronization(Synchronization synchronizedObserver) {
              
              
                      try {
                          TransactionSynchronizationRegistry reg = ((TransactionSynchronizationRegistry) ctx.lookup(TransactionManagerServices.getConfiguration().getJndiTransactionSynchronizationRegistryName()));
                          reg.registerInterposedSynchronization(synchronizedObserver);
                      } catch (NamingException e) {
                          e.printStackTrace();
                      }
                  }
              
              
                  @Override
                  public boolean isTransactionActive() {
                      try {
              
                          return getUserTransaction().getStatus() == Status.STATUS_ACTIVE;
                      } catch (final Exception e) {
                          return false;
                      }
                  }
              
              
                  @Override
                  public UserTransaction getUserTransaction() {
                      try {
                           return (UserTransaction) ctx.lookup(TransactionManagerServices.getConfiguration().getJndiUserTransactionName());
                      } catch (NamingException e) {
                          e.printStackTrace();
                      }
                      return null;  //To change body of implemented methods use File | Settings | File Templates.
                  }
              
              
                  @Override
                  public void cleanup() {
                  }
              }
              
              
              
              
              
              
              
              • 4. Re: Re: Bootstrap JTA in unit test
                tomjenkinson

                Hi,

                 

                I am not too sure what you mean by can't plug it into Weld? Do you mean that you can't lookup the transaction manager and transaction synchronization registry via JNDI?

                 

                Tom

                • 5. Re: Re: Bootstrap JTA in unit test
                  vasilievip

                  Yes, I can't find good example here. I see this one, but it looks like related to JCA adapter:

                  quickstart/jca-and-tomcat/src/test/resources/jndi.properties at master · jbosstm/quickstart · GitHub

                  I guess the jndi setup does not mean that it will bootstrap all JTA related services?

                  java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

                  java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

                   

                  I also do not see how to use/activate @Transactional interceptor for CDI. Any suggestion here?

                  • 6. Re: Re: Bootstrap JTA in unit test
                    paul.robinson

                    Ivan,

                     

                    The @Transactional feature is well integrated with WildFly, which makes it very easy to use in WildFly. However, I'm not sure how well it works outside of WildFly.However, it is implemented using standard CDI interceptors, so it should work. You would just need to activate the interceptors in the same way as you would any other CDI interceptor. I'm being intentionally vague here, as it's not something I've done outside of WildFly, but the Weld docs should help here.

                     

                    As this is not something we have tried, you may run into issues along the way. However, I don't yet see anything fundamental that would stop this working, so we should be able to fix any issues you encounter.

                     

                    I would suggest you start by writing your own simple CDI interceptor and getting that enabled. Then you could try enabling the @Transactional interceptors and testing the behaviour. The best examples we have at the moment is our Arquillian tests [1]. I know you don't want to use Arquillian and WildFly, but you should be able to pick out just the CDI bits. 

                     

                    Paul.

                     

                    [1] narayana/ArjunaJTA/cdi/tests/classes/com/hp/mwtests/ts/jta/cdi/transactional/TestTransactionalBean.java at master · jbos…

                    • 7. Re: Re: Bootstrap JTA in unit test
                      vasilievip

                      Thanks, it looks like I have to take some code from appserver for this. I was already looking on glassfish interceptors

                      Regarding arquillian - don't get me wrong - its a great tool for integration testing between containers, like to make sure that my app works on all set of them. But the hack with packaging my application in unit test is something I do not understand and I feel that there is a better way.

                      With new CDI I think there is finally way to get unit testing lightweight (just like you can get it with spring, but w/o dependencies to spring) - just plug in-memory environment and test on existing classpath.

                      • 8. Re: Re: Re: Bootstrap JTA in unit test
                        tomjenkinson

                        Hi Ivan,


                        The jca-and-hibernate qs we recently added should demonstrate the lookup of the transaction manager:

                        https://github.com/jbosstm/quickstart/blob/master/jca-and-hibernate/src/main/java/org/jboss/narayana/quickstart/hibernate/CustomerManager.java#L42

                         

                        As JNDI is not a requirement of JTA we are using IronJacamar in our quickstarts to illustrate how you can get access via JNDI to java:/TransactionManager, java:/UserTransaction and java:/TransactionSynchronizationRegistry. We are also using IJ in this QS as it provides access to the datasources.

                         

                        I have raised JBTM-2049 to provide a quickstart for the @Transactional JTA 1.2 APIs we support, Gytis is taking a look at it now. As Paul mentioned, if you are interested in working with us on please do ping one of us on #jbossts (freenode irc).

                         

                        Many thanks,

                        Tom

                        • 9. Re: Re: Re: Bootstrap JTA in unit test
                          vasilievip

                          Tom Jenkinson wrote:

                          As JNDI is not a requirement of JTA we are using IronJacamar in our quickstarts to illustrate how you can get access via JNDI to java:/TransactionManager, java:/UserTransaction and java:/TransactionSynchronizationRegistry. We are also using IJ in this QS as it provides access to the datasources.

                          Well, JNDI setup can be plugged into deltaspike core:

                          https://github.com/apache/deltaspike/blob/master/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java#L51

                          Plus they have an custom @Transactional (I mean not referencing 1.2 spec) annotation and handling interceptor

                          deltaspike/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionalInterceptor…

                          • 10. Re: Re: Bootstrap JTA in unit test
                            mmusgrov

                            I guess the jndi setup does not mean that it will bootstrap all JTA related services?

                            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

                            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

                             

                            FYI, you will need to provide the JNDI setup and we only bind the standard JTA "services"  (UserTransaction, TransactionManager and TransactionSynchronizationRegistry). You can do this by calling com.arjuna.ats.jta.utils.JNDIManager#bindJTAImplementation()

                             

                            Either pass that call a context or set the appropriate JVM system properties: System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "your chosen JNDI implementation") and System.setProperty(Context.PROVIDER_URL, "...").

                            1 of 1 people found this helpful
                            • 11. Re: Bootstrap JTA in unit test
                              gytis

                              Hello,

                               

                              I have raised a pull request with a new quickstart: Standalone JTA 1.2 quickstart by Gytis · Pull Request #111 · jbosstm/quickstart · GitHub

                               

                              Hope it helps,

                              Gytis

                              • 12. Re: Bootstrap JTA in unit test
                                vasilievip

                                This looks very helpful!

                                Will try to plug it into junit CDI runner from detltaspike.

                                • 13. Re: Bootstrap JTA in unit test
                                  vasilievip

                                  I've made an attempt to integrate JTA into deltaspike, but can't understand whats wrong at this point:

                                  Add JPA testcase which demonstrates synchronization issue by vasilievip · Pull Request #112 · jbosstm/quickstart · GitHu…

                                   

                                  - If there is no "flush" invocation on EntityManager - then no data hits database at all

                                  - If there is "flush" invocation on EntityManager - then "no transaction in progress"

                                   

                                  I'm not really sure if root cause is in narayana or hibernate.

                                  • 14. Re: Bootstrap JTA in unit test
                                    tomjenkinson

                                    Hi Ivan,

                                     

                                    Its not really the best way to report an issue by raising a pull request on the QS repo, that being said I think Gytis has answered your question on the PR?

                                     

                                    Thanks,

                                    Tom

                                    1 2 Previous Next