6 Replies Latest reply on Aug 18, 2011 7:36 PM by Chris Lowe

    AS7 Quartz Async + Transactions: could not discover transaction status

    Chris Lowe Apprentice

      Hello,


      I have a transactional asynchronous Quartz task that has starting acting up since migrating to AS7.  The application is WAR based and I'm using Seam 2.2.2.Final. The problem I'm having that every time an async process is fired, I see the error message could not discover transaction status in the logs.


      I've had a bit of a dig around and made comparisons with how things were working under AS6 and it looks like there has been a change with how AS7 handles resource requests from non-EE threads.  In this case am I right in thinking that the Quartz workers would be non-EE threads?  I came to that conclusion after reading through this discussion:


      http://lists.jboss.org/pipermail/jboss-as7-dev/2011-June/002290.html


      The error message is produced from org.jboss.seam.contexts.Contexts.flushAndDestroyContexts() but the error originates from Transactional.getUserTransaction(). The following method is failing under AS7 but works under AS6:


       protected javax.transaction.UserTransaction getUserTransaction() throws NamingException
         {
            InitialContext context = Naming.getInitialContext();
            try
            {
               return (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction");
            }
            catch (NameNotFoundException nnfe)
            {
               try
               {
                  //Embedded JBoss has no java:comp/UserTransaction
                  javax.transaction.UserTransaction ut = (javax.transaction.UserTransaction) context.lookup("UserTransaction");
                  ut.getStatus(); //for glassfish, which can return an unusable UT
                  return ut;
               }
               catch (Exception e)
               {
                  throw nnfe;
               }
            }
         }



      Under AS6 the first lookup fails, the NameNotFoundException exception handler is invoked and the next call to lookup succeeds.


      Interestingly, the discussion I linked to above also suggests that the above scenario (i.e. accessing a global resource from a non-EE thread) is handled specially by AS6.


      Under AS7 the first lookup fails but does not even generate a NameNotFoundException, it just generates a NamingException (which sort of sounds like JBSEAM-2025?).  With that in mind, as a test I modified and built the source shipped with Seam to handle NamingException to force the lookup using the global UserTransaction resource name.  Unfortunately that also failed.


      Does anyone know of a workaround for this?


      Cheers,


      Chris.

        • 1. Re: AS7 Quartz Async + Transactions: could not discover transaction status
          zeeman Novice

          I have the same exception for a war I migrated to AS7. I'm not using Quartz, just raising an async event, in observer it's a transactional method and I get above exception.



          Any ideas?

          • 2. Re: AS7 Quartz Async + Transactions: could not discover transaction status
            Chris Lowe Apprentice

            It occurred to me that AS6 has a quartz resource adaptor (quartz-ra.rar) in the default server configuration which is not present under AS7.


            https://itdevworld.wordpress.com/2010/01/05/quartz-resource-adapter-as-an-alternative-to-ejb-timers/


            Right now, I'm just thinking out loud and I'm not sure if this is helpful to this particular case (this delves a little deeper into JBoss than I'd normally go).  I'll pick this up later as I have to get on with my day job...


            If in the meantime anyone has ideas or input, please feel free to add your thoughts.


            Chris.

            • 3. Re: AS7 Quartz Async + Transactions: could not discover transaction status
              Chris Lowe Apprentice

              I've raised question of accessing UserTransaction from a non-EE thread on the AS7 forum


              http://community.jboss.org/message/616375


              It looks as if the global transaction is not available in 7.0.0 however there is a good chance that a global UserTransaction may be available in a future version via the JNDI name java:/jboss/UserTransaction, see the AS7 thread above and the following Jira issue:


              https://issues.jboss.org/browse/AS7-1358


              I was successful in my endeavours in patching AS7 to handle the new JNDI but I also had to extend the default Seam Transaction component to account for the fact that I was just getting a NamingException (rather that a NameNotFoundException) and to use the JNDI java:/jboss/UserTransaction.


              Fortunately Seam's Install precedence makes this a breeze, so here's the AS7 component I made to override default Seam behaviour:


              import static org.jboss.seam.annotations.Install.*;
              
              import javax.naming.InitialContext;
              import javax.naming.NamingException;
              import javax.transaction.UserTransaction;
              
              import org.jboss.seam.ScopeType;
              import org.jboss.seam.annotations.Install;
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Scope;
              import org.jboss.seam.annotations.intercept.BypassInterceptors;
              import org.jboss.seam.transaction.Transaction;
              import org.jboss.seam.util.Naming;
              
              @Name("org.jboss.seam.transaction.transaction")
              @Scope(ScopeType.EVENT)
              @Install(precedence = APPLICATION) // overrides Seam default component of BUILT_IN
              @BypassInterceptors
              public class TransactionAs7 extends Transaction {
              
                   @Override
                   protected UserTransaction getUserTransaction() throws NamingException {
                        final InitialContext context = Naming.getInitialContext();
              
                        try {
                             return (UserTransaction) context.lookup("java:comp/UserTransaction");
                        } catch (final NamingException ne) {
                             try {
                                  // JBoss AS7 (with patch from https://issues.jboss.org/browse/AS7-1358)
                                  return (UserTransaction) context.lookup("java:jboss/UserTransaction");
                             } catch (final Exception cause) {
                                  // ignore this so we let the code carry on to try the final JNDI name
                             }
              
                             try {
                                  // Embedded JBoss has no java:comp/UserTransaction
                                  final UserTransaction ut = (UserTransaction) context.lookup("UserTransaction");
                                  ut.getStatus(); // for glassfish, which can return an unusable UT
                                  return ut;
                             } catch (final Exception e) {
                                  throw ne;
                             }
                        }
                   }
              
              }




              Obviously this will need JBoss AS7 patch to support the new JNDI name, please add a watch to the Jira above for status updates.


              Regards,


              Chris.

              • 4. Re: AS7 Quartz Async + Transactions: could not discover transaction status
                Chris Lowe Apprentice

                My AS patch has been accepted and will be part of the AS 7.0.1 release, see AS7-1358 for details.

                • 5. Re: AS7 Quartz Async + Transactions: could not discover transaction status
                  Ben Kirby Newbie

                  We've had a similar issue with non-EE threads - thanks to all the work you've put into this, we've fixed it in the same way.


                  We're using Seam 3, however, and can't seem to find the equivalent of the Seam 2 annotations (@Install, etc). As a workaround, we've patched and compiled the actual DefaultSeamTransaction class, so it tries on the AS7 JNDIName.


                  It would be much nicer to be able to create and install our own Transaction, as you detail above. Could you - or anyone else! - point me to some documentation for how to do this with Seam 3 projects?


                  Thanks,
                  Ben

                  • 6. Re: AS7 Quartz Async + Transactions: could not discover transaction status
                    Chris Lowe Apprentice

                    Hi Ben,


                    Sorry, I have not used Seam 3 yet.  Hopefully someone else will be able to comment.


                    Regards,


                    Chris.