1 Reply Latest reply on Dec 29, 2003 3:56 AM by Adrian Brock

    Transacted JMS from a client applicaton -> Invalid transacti

    Andreas Buschka Newbie

      I have a stand-alone client application that should do two things in a transaction:

      1. Call a method in a session facade session bean (which changes the database)
      2. Send a JMS message to a queue

      Session facade bean and JMS queue are on the same JBoss server.

      When I try my code, the transaction starts fine, the EJB operations perform, but when the command "send.send(tm);" (see below) is execute, I get the following stackdump:

      javax.jms.JMSException: Invalid transaction id.
      at org.jboss.mq.SpyXAResourceManager.addMessage(SpyXAResourceManager.java:95)
      at org.jboss.mq.SpySession.sendMessage(SpySession.java:695)
      at org.jboss.mq.SpyQueueSender.internalSend(SpyQueueSender.java:118)
      at org.jboss.mq.SpyQueueSender.send(SpyQueueSender.java:68)
      at de.fernunihagen.notifyme.clients.WartungsDaemon.WartungsDaemonMain.jobBenachrichtigungen(WartungsDaemonMain.java:132)
      at de.fernunihagen.notifyme.clients.WartungsDaemon.WartungsDaemonMain.start(WartungsDaemonMain.java:191)
      at de.fernunihagen.notifyme.clients.WartungsDaemon.WartungsDaemonMain.main(WartungsDaemonMain.java:205)

      This is the code:

      void initialize() {
      ...
      // BenachrichtigungSessionFacade:
      ref = context.lookup("BenachrichtigungSessionFacade");
      benachrichtigungSfHome = (BenachrichtigungSessionFacadeHome) PortableRemoteObject.narrow(ref, BenachrichtigungSessionFacadeHome.class);
      benachrichtigungSf = benachrichtigungSfHome.create();

      // Besorge den Zugriff auf unsere Nachrichten-Queue (Benachrichtigungs-Adapter)
      qcf = (XAQueueConnectionFactory)context.lookup("XAConnectionFactory");
      conn = qcf.createXAQueueConnection(queueBenutzerName, queuePasswort);
      que = (Queue)context.lookup(queueBezeichnungBenachrichtigungsAdapter);
      ...
      }


      void jobBenachrichtigungen() {
      try {
      log.debug("Suche nach Benachrichtigungen...");
      BenachrichtigungDto[] benachrichtigungen =
      benachrichtigungSf.benachrichtigungFindByStatus(new Integer(
      BenachrichtigungStatus.STATUS_WARTE_AUF_NEUSTART));

      if (benachrichtigungen.length>0) {
      // Das Ganze muss in einer Transaktion stattfinden, damit die Benachrichtigung
      // nicht scheinbar bearbeitet liegen bleibt:
      UserTransaction tran = (UserTransaction)
      context.lookup("UserTransaction");
      for (int i=0; i<benachrichtigungen.length; i++) {
      BenachrichtigungDto benachrichtigung = benachrichtigungen;

      // Schuetze die beiden Operationen Status-Setzen und Nachricht-Schicken
      // davor, durch Fehler auseinandergerissen zu werden.
      tran.begin();

      // Setze den Status der Nachricht auf "neu":
      benachrichtigung.setStatus(new Integer(BenachrichtigungStatus.STATUS_NEU));
      benachrichtigungSf.updateBenachrichtigung(benachrichtigung);

      // Benachrichte die Benachrichtigungs-Adapter, dass die Benachrichtigung
      // ausgeliefert werden soll.
      session = conn.createXAQueueSession();

      conn.start();
      QueueSender send = session.getQueueSession().createSender(que);
      ObjectMessage tm = session.createObjectMessage(benachrichtigung);
      tm.setStringProperty("MessageFormat", "Benachrichtigung");
      tm.setStringProperty("MessageFormatVersion", "1.0");
      tm.setIntProperty("AusgabeFormatId", benachrichtigung.getAusgabeFormat().getId().intValue());
      send.send(tm); <-- CRASH OCCURS HERE
      send.close();
      session.commit();

      // Bestaetige die Transaktion
      tran.commit();

      }
      } else {
      log.debug("Es gibt keine Benachrichtigungen, die bearbeitet werden muessen.");
      }
      }