8 Replies Latest reply on Dec 11, 2001 5:04 PM by michel1

    Invalid transaction id

    michel1

      I'm trying to post a message from within a session bean to a topic. I'm getting JMSException: invalid transaction id, and I'm really stuck now. Please help!

      I've followed the JMS with managed resource example in the free documentation, running on JBoss 2.4.0.

      This is (part of) the ejb-jar.xml:

      <ejb-name>com.daisy.store.events.PublishEvent</ejb-name>
      com.daisy.store.events.PublishEventHome
      com.daisy.store.events.PublishEvent
      <ejb-class>com.daisy.store.events.PublishEventEJB</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
      <resource-ref>
      The Transaction managed Topic ConnectionFactory
      <res-ref-name>jms/MyTopicConnection</res-ref-name>
      <res-type>javax.jms.TopicConnectionFactory</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>
      <resource-ref>
      Daisy Store change topic
      <res-ref-name>jms/DaisyStoreChanges</res-ref-name>
      <res-type>javax.jms.Topic</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>




      This is the jboss.xml:


      <resource-managers>
      <resource-manager>
      <res-name>topicfactoryref</res-name>
      <res-jndi-name>java:/INVMXATopicConnectionFactory</res-jndi-name>
      </resource-manager>
      <resource-manager>
      <res-name>topicref</res-name>
      <res-jndi-name>topic/daisyStoreChanges</res-jndi-name>
      </resource-manager>
      </resource-managers>

      <enterprise-beans>


      <ejb-name>com.daisy.store.events.PublishEvent</ejb-name>
      <jndi-name>com.daisy.store.events.PublishEvent</jndi-name>
      <configuration-name>Standard Stateless SessionBean</configuration-name>
      <resource-ref>
      <res-ref-name>jms/MyTopicConnection</res-ref-name>
      <resource-name>topicfactoryref</resource-name>
      </resource-ref>
      <resource-ref>
      <res-ref-name>jms/DaisyStoreChanges</res-ref-name>
      <resource-name>topicref</resource-name>
      </resource-ref>

      </enterprise-beans>



      This is the session ejb implementation:
      (init is called first, then publish)

      /**
      * Publish the given String as a JMS message to the topic.
      */
      private void doPublish(String action, String name)
      throws JMSException {
      TopicSession topicSession = null;
      TopicPublisher topicPublisher;

      Log log = new Log(this.getClass());
      log.debug("Publish in session bean called");

      try {
      // Create the session; transaction managed if this thread has
      // an associated transaction; must be recreated for
      // each transaction (we do it for each call)
      try {
      log.debug("creating session for transaction "+
      context.getUserTransaction());
      log.debug("transaction?:"+(context.getUserTransaction().getStatus()!=Status.STATUS_NO_TRANSACTION));
      topicSession = topicConnection.createTopicSession(
      (context.getUserTransaction().getStatus()!=Status.STATUS_NO_TRANSACTION),
      Session.AUTO_ACKNOWLEDGE);
      } catch (SystemException e) {
      log.error(e);
      }
      // Create a publisher
      topicPublisher = topicSession.createPublisher(topic);

      // Create a message
      TextMessage message = topicSession.createTextMessage();
      message.setStringProperty(EventConstants.ACTION_KEY, action);
      message.setStringProperty(EventConstants.NAME_KEY, name);

      // Publish the message
      topicPublisher.publish(topic, message);
      } finally {
      // close the session; it is pooled by the container
      if (topicSession != null) {
      topicSession.close();
      }
      }

      // close the
      }

      public void init()
      throws JMSException, NamingException {

      // Get the initial context
      Context context = new InitialContext();

      // Get the connection factory
      TopicConnectionFactory topicFactory = (TopicConnectionFactory)context.lookup(CONNECTION_FACTORY);

      // Create the connection
      topicConnection = topicFactory.createTopicConnection();

      // Look up the destination
      topic = (Topic)context.lookup(TOPIC);
      }


      Some jndi definitions:
      private static String CONNECTION_FACTORY = "java:/INVMXATopicConnectionFactory";

      /** The topic to use; defined in ejb-jar.xml */
      private static String TOPIC = "java:comp/env/jms/DaisyStoreChanges";


      In jbossmq.xml:
      daisyStoreChanges


      There are no ClassCast, NullPointer, NamingExceptions.

      I need the JMS messages to be in the transaction context, because they must only be delivered on successful commit, and not before the commit (otherwise a nasty deadlock results).

      Any suggestions are welcome!

      Sincerely,
      Michel de Groot

        • 1. Re: Invalid transaction id

          Hi,
          it does not look as if you are folowing the manual.
          A kee part of the configuration for JMS as a managed resource looks like this in the manual:

          <resource-managers>
          <resource-manager>
          <res-name>topicfactoryref</res-name>
          <res-jndi-name>java:/JmsXA</res-jndi-name>
          </resource-manager>
          <resource-manager>
          <res-name>topicref</res-name>
          <res-jndi-name>topic/testTopic</res-jndi-name>
          </resource-manager>
          </resource-managers>

          And I can't see that you are using the JMS JCA RA. Instead it looks as if you are manually looking up an XA connection factory - which should never ever be done in client code.

          But I might have understood your code wrong. It is so hard to read unindented code.

          //Peter

          • 2. Re: Invalid transaction id
            michel1

            Hi Peter,

            I moved the lookup of topic and creation of connection to the ejbCreate() method; changed the resource JNDI name in jboss.xml to java:/JmsXA.

            Now I get a 'javax.naming.NameNotFoundException: JmsXA not bound' exception. Checked jboss.jcml, but JmsXA is listed there.

            What could I be doing wrong?

            Sincerely,
            Michel

            • 3. Re: Invalid transaction id

              Very hard to say what is going wrong. Take a look in the management gui (port 8082) and check the JNDIView bean to get a list of all names available in JNDI.

              //Peter

              • 4. Re: Invalid transaction id
                michel1

                JmsXA is bound *after* the autodeployer, which in my case starts a servlet which publishes a message, which causes the lookup to fail at this moment.

                How can I stop the autodeployer from deploying the .ear before JmsXA is started?

                • 5. Re: Invalid transaction id
                  michel1

                  I solved it by creating a second autodeployer in jboss.jcml, at the end. See the JMX forum.

                  • 6. Re: Invalid transaction id

                    Hm, thats strange. Are we talking jboss2.4.[3|4] here. Then the JMS JCA should be moved to before the autodeployer.

                    Looking into my 2.4 line version having here localy the auto deployer is after JmsXA.

                    //Peter

                    • 7. Re: Invalid transaction id
                      michel1

                      In mine it was too. But J2eeDeployer in ../deploy was mentioned first, and this apparently was processed first.

                      • 8. Re: Invalid transaction id
                        michel1

                        In mine it was too. But J2eeDeployer in ../deploy was mentioned first, and this apparently was processed first.