1 2 Previous Next 20 Replies Latest reply: Jan 9, 2014 11:28 AM by Ivan Vasyliev RSS

Bootstrap JTA in unit test

Ivan Vasyliev Newbie

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
    Tom Jenkinson Master

    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/

  • 2. Re: Bootstrap JTA in unit test
    Ivan Vasyliev Newbie

    Let me look into. Thanks!

  • 3. Re: Re: Bootstrap JTA in unit test
    Ivan Vasyliev Newbie

    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
    Tom Jenkinson Master

    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
    Ivan Vasyliev Newbie

    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 Master

    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
    Ivan Vasyliev Newbie

    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
    Tom Jenkinson Master

    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
    Ivan Vasyliev Newbie

    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
    Michael Musgrove Master

    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, "...").

  • 11. Re: Bootstrap JTA in unit test
    Gytis Trikleris Newbie

    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
    Ivan Vasyliev Newbie

    This looks very helpful!

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

  • 13. Re: Bootstrap JTA in unit test
    Ivan Vasyliev Newbie

    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
    Tom Jenkinson Master

    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