8 Replies Latest reply on Mar 10, 2010 8:59 PM by Scott Zhang

    Integration with JBoss AS4

    Scott Zhang Newbie

      I integrate HornetQ 2.0.0-GA to JBoss AS 4.2.2-GA, when call HornetQ from multi-thread session bean throught Resource Adapter (JmsXA), it throws exception:{quote}

      20:23:31,203 WARN  [loggerI18N] [com.arjuna.ats.internal.jta.resources.arjunacore.commitxaerror] [com.arjuna.ats.interna l.jta.resources.arjunacore.commitxaerror] XAResourceRecord.commit - xa error XAException.XAER_PROTO {quote}

      the calling sequence is:

      Client call Session Bean call JmsXA

       

      When client is running single thread, it's ok, but when client is running with multi-threads, the exception above was throwed,

      The session bean is a simple CMT bean, some code snippet like this: {code:java} @TransactionAttribute(TransactionAttributeType.REQUIRED) public void test(Serializable obj) throws BusinessException {   InitialContext ctx = new InitialContext();   ConnectionFactory factory = (ConnectionFactory) ctx.lookup("java:/JmsXA");   Destination dest = (Topic) ctx.lookup("topic/testTopic");   Connection connection = factory.createConnection();   Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);   MessageProducer producer = session.createProducer(dest);   ObjectMessage msg = session.createObjectMessage();   msg.setObject(obj);   producer.send(msg);     // do something else and close session   ... } {code} Where is the problem?

        • 1. Re: Integration with JBoss AS4
          Scott Zhang Newbie
          Are there some bugs in HornetQ or incorrent configuration ?
          • 2. Re: Integration with JBoss AS4
            Clebert Suconic Master

            It isn't really clear what you're doing. So, we can't really tell what you're doing wrong.

             

            For instance I have no idea what you mean by "from multi-thread session bean"

             

            You're not supposed to start a thread from a SessionBean. The context is associated with a thread. so you're probably breaking the TM's contract.

             

            You should probably ask this on the JBoss user's forum. I don't think the issue you have is realted to HornetQ.

            • 3. Re: Integration with JBoss AS4
              Scott Zhang Newbie

              May be my expression is not clear. The client program: {code:java} public class Test {   public static void main(String[] args) throws Exception {     Product p = new Product();     for (int i = 0; i < 10; i++)       new TestThread(p).start();   }   static class TestThread extends Thread {     private Product p;     public TestThread(Product p) {       this.p = p;     }     public void run() {       try {         Hashtable env = new Hashtable();         env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");         env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");         env.put("java.naming.provider.url", "localhost:1099");         InitialContext ctx = new InitialContext(env);         ITestBean ms = (ITestBean) ctx.lookup("TestBean/remote");         for (int i = 1; i < 100; i++) {           ms.test(p);           System.out.println(i);           try {             Thread.sleep(10);           } catch (Exception e) {           }         }       } catch (Exception e) {         e.printStackTrace();       }     }   } } {code} The Session Bean Program: {code:java} @Stateless(name = "TestBean") @Local(ITestBean.class) @Remote(ITestBean.class) @PersistenceContexts(value = {   @PersistenceContext(name = "testpu", unitName = "testpu") }) public class TestBean implements ITestBean {   //...   @TransactionAttribute(TransactionAttributeType.REQUIRED)   public void test(Serializable obj) throws BusinessException {     InitialContext ctx = new InitialContext();     ConnectionFactory factory = (ConnectionFactory) ctx.lookup("java:/JmsXA");     Destination dest = (Topic) ctx.lookup("topic/testTopic");     Connection connection = factory.createConnection();     Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);     MessageProducer producer = session.createProducer(dest);     ObjectMessage msg = session.createObjectMessage();     msg.setObject(obj);     producer.send(msg);         // do something else and close session     // ...   } } {code}

              When run Test, the exception throwed.
              • 4. Re: Integration with JBoss AS4
                Scott Zhang Newbie

                I found that when the method test() contains only sending message codes and do nothing else,

                the exception is not thrown, but the messages is NOT really writen into the queue (viewed from jmx-console).

                 

                From the log, I see these:

                {quote}

                2010-03-10 11:07:01,890 TRACE [org.hornetq.ra.HornetQRAXAResource] end(< 131075, 28, 26, 1--3f57f160:f8e:4b970c70:22b-3f57f160:f8e:4b970c70:22d

                ...

                2010-03-10 11:07:01,890 TRACE [org.hornetq.ra.HornetQRAXAResource] commit(< 131075, 28, 26, 1--3f57f160:f8e:4b970c70:22b-3f57f160:f8e:4b970c70:22d

                {quote}

                 

                I doubt when the transaction is really commited.

                 

                I modify the example "ejb-jms-transaction" in 2.0.0.GA release, replace EJBClientExample.java with multi threads, 

                running result is also thrown exception like me.

                 

                the modified EJBClientExample code likes (I deleted some unnecessary code):

                {code:java}

                public class TestHornetQ {   public static void main(final String[] args) throws Exception {     for (int i = 0; i < 10; i++)       new TestThread().start();   }   static class TestThread extends Thread {     public void run() {       try {         InitialContext initialContext = null;         try {           // Step 1. Obtain an Initial Context           Hashtable env = new Hashtable();           env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");           env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");           env.put("java.naming.provider.url", "localhost:1099");           initialContext = new InitialContext(env);           // Step 2. Lookup the EJB           SendMessageService service = (SendMessageService) initialContext               .lookup("SendMessageBean/remote");           // Step 4. Invoke the sendAndUpdate method           for (int i = 1; i <= 99; i++) {             service.sendAndUpdate("This is a text message");             System.out.println("invoked the EJB service");           }         } finally {           // Step 10. Be sure to close the resources!           if (initialContext != null) {             initialContext.close();           }         }       } catch (Exception e) {         System.out.println(e.getMessage());       }     }   } }

                {code}

                the modify SendMessageBean code like this:

                {code:java}

                @Stateless(name = "SendMessageBean") @Remote(SendMessageService.class) public class SendMessageBean implements SendMessageService {   public void sendAndUpdate(final String text) throws Exception {     InitialContext ic = null;     Connection jmsConnection = null;     java.sql.Connection jdbcConnection = null;     try {       // Step 1. Lookup the initial context       ic = new InitialContext();       // JMS operations       // Step 2. Look up the XA Connection Factory       ConnectionFactory cf = (ConnectionFactory) ic.lookup("java:/JmsXA");       // Step 3. Look up the Queue       Queue queue = (Queue) ic.lookup("queue/TestQ");       // Step 4. Create a connection, a session and a message producer for the       // queue       jmsConnection = cf.createConnection();       Session session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);       MessageProducer messageProducer = session.createProducer(queue);       // Step 5. Create a Text Message       TextMessage message = session.createTextMessage(text);       // Step 6. Send The Text Message       messageProducer.send(message);       System.out.println("Sent message: " + message.getText() + "(" + message.getJMSMessageID()           + ")");       // DB operations       // Step 7. Look up the XA Data Source       DataSource ds = (DataSource) ic.lookup("java:/DefaultDS");       // Step 8. Retrieve the JDBC connection       jdbcConnection = ds.getConnection();       // Step 9. Create the prepared statement to insert the text and the       // message's ID in the table       PreparedStatement pr = jdbcConnection.prepareStatement("insert into test(x) values('" + text           + "')");       // Step 10. execute the prepared statement       pr.execute();       // Step 11. close the prepared statement       pr.close();     } finally {       // Step 12. Be sure to close all resources!       if (ic != null) {         ic.close();       }       if (jmsConnection != null) {         jmsConnection.close();       }       if (jdbcConnection != null) {         jdbcConnection.close();       }     }   } }

                {code}

                Anything more I can do ?

                • 5. Re: Integration with JBoss AS4
                  Clebert Suconic Master

                  Why do you think this is an error?

                   

                  2010-03-10 11:07:01,890 TRACE org.hornetq.ra.HornetQRAXAResource end(&lt; 131075, 28, 26, 1--3f57f160:f8e:4b970c70:22b-3f57f160:f8e:4b970c70:22d

                  ...

                  2010-03-10 11:07:01,890 TRACE org.hornetq.ra.HornetQRAXAResource commit(&lt; 131075, 28, 26, 1--3f57f160:f8e:4b970c70:22b-3f57f160:f8e:4b970c70:22d

                   

                   

                   

                  This is just a debug trace logging (that you probably activated at your server), saying that commit happened properly.

                  • 6. Re: Integration with JBoss AS4
                    Clebert Suconic Master

                    BTW: this would be a question more to the transaction's team.

                     

                     

                    If you still have an issue with Hornetq.. I would kindly ask you to really think about your scenario and try explaining it in just a few simple sentences. (Maybe that would help even you.. as you might see what's happening in a clearer way).

                    • 7. Re: Integration with JBoss AS4
                      Scott Zhang Newbie

                      Sorry, this is just my debug to see what happend with transaction, NOT error.

                      • 8. Re: Integration with JBoss AS4
                        Scott Zhang Newbie

                        I just doubt whether the Resouce Adapter implementation of HornetQ is thread-safe,

                        because the same test is ok when using JBoss Messaging 1.4.2.-SP1.

                         

                        I attach a picture to show the test.

                        the Client is running in multi-thread scenario.