2 Replies Latest reply on Aug 5, 2002 10:24 AM by jweis

    MDB durable subscriber

    jweis

      In JBoss3.0, I would like to have a Message Driven Bean listening as a durable subscriber to another instance of Jboss (on another machine) that hosts the topic and the publisher. I am fairly new to MDB and EJB and have been unsuccessful.

      Here is what I have done:

      ejb-jar.xml:

      <?xml version="1.0"?>

      <ejb-jar>
      <enterprise-beans>
      <message-driven>
      <ejb-name>MyTextMDB</ejb-name>
      <ejb-class>jbossmqejb.MyTextMDB</ejb-class>
      <message-selector></message-selector>
      <transaction-type>Container</transaction-type>
      <message-driven-destination>
      <destination-type>javax.jms.Topic</destination-type>
      </message-driven-destination>
      </message-driven>
      </enterprise-beans>
      <assembly-descriptor>
      <container-transaction>

      <ejb-name>MyTextMDB</ejb-name>
      <method-name>*</method-name>

      <trans-attribute>NotSupported</trans-attribute>
      </container-transaction>
      </assembly-descriptor>
      </ejb-jar>

      jboss.xml:
      <?xml version="1.0"?>

      <enterprise-beans>
      <message-driven>
      <ejb-name>MyTextMDB</ejb-name>
      <configuration-name>My Message Driven Config</configuration-name>
      <destination-jndi-name>topic/jasonTopic</destination-jndi-name>
      <subscription-durability>Durable</subscription-durability>
      <mdb-user>jason</mdb-user>
      <mdb-passwd>foobar</mdb-passwd>
      <mdb-subscription-id>foo</mdb-subscription-id>
      </message-driven>
      </enterprise-beans>
      <container-configurations>
      <container-configuration>
      <container-name>My Message Driven Config</container-name>
      <call-logging>false</call-logging>
      <container-invoker>org.jboss.ejb.plugins.jms.JMSContainerInvoker</container-invoker>
      <container-interceptors>
      org.jboss.ejb.plugins.LogInterceptor
      org.jboss.ejb.plugins.SecurityInterceptor
      <!-- CMT
      org.jboss.ejb.plugins.TxInterceptorCMT
      org.jboss.ejb.plugins.MetricsInterceptor
      org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor
      -->
      <!-- BMT
      org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor
      org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT
      org.jboss.ejb.plugins.MetricsInterceptor
      -->
      </container-interceptors>
      <instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePool</instance-pool>
      <instance-cache></instance-cache>
      <persistence-manager></persistence-manager>
      <transaction-manager>org.jboss.tm.TxManager</transaction-manager>
      <container-invoker-conf>
      RemoteJMSProvider
      StdJMSPool
      15
      1
      True
      </container-invoker-conf>
      <container-pool-conf>
      100
      10
      </container-pool-conf>
      </container-configuration>
      </container-configurations>


      MDB Code:
      package jbossmqejb;

      import javax.ejb.MessageDrivenContext;
      import javax.ejb.MessageDrivenBean;
      import javax.jms.Message;
      import javax.jms.MessageListener;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.jms.TopicConnectionFactory;
      import javax.jms.TopicConnection;
      import javax.jms.TopicSession;
      import javax.jms.TopicSubscriber;
      import javax.jms.Topic;
      import javax.jms.TextMessage;
      import javax.jms.Session;
      import javax.jms.JMSException;
      import javax.jms.Message;
      import java.util.*;
      import java.io.*;

      public class MyTextMDB implements MessageDrivenBean, MessageListener {


      private MessageDrivenContext ctx = null;
      private TopicConnection tc;
      private TopicSession ts;




      /**
      * Get session and topic connection.
      * @throws EJBException
      */
      public void ejbCreate() throws javax.ejb.EJBException {

      try
      {

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

      // Get the topic connection factory
      TopicConnectionFactory topicFactory = (TopicConnectionFactory)context.lookup("UILConnectionFactory");

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

      // Create the session
      ts = tc.createTopicSession(
      // No transaction
      false,
      // Auto ack
      Session.AUTO_ACKNOWLEDGE);

      tc.start();

      }
      catch(Exception e)
      {
      throw new javax.ejb.EJBException("Failed to init MyTextMDB", e);
      }

      }

      /**
      *
      * On remove close session and topic connections.
      */
      public void ejbRemove() throws javax.ejb.EJBException {


      System.out.println("Closing session and topic connections.");
      ctx = null;
      try
      {
      if(ts != null)
      ts.close();
      if(tc != null)
      tc.close();

      }
      catch(Throwable t)
      {
      t.printStackTrace();
      }


      }

      public void setMessageDrivenContext(MessageDrivenContext mdc) throws javax.ejb.EJBException {
      ctx = mdc;
      }

      // Print message to console.
      public void onMessage(Message msg) {

      try
      {
      TextMessage tm = (TextMessage)msg;
      String text = tm.getText();
      System.out.println(text);

      }
      catch(Throwable t)
      {
      t.printStackTrace();
      }

      }
      }


      Snippet from jms-service.xml

      RemoteJMSProvider

      org.jboss.jms.jndi.JBossMQProvider

      gram:1099
      java:/XAConnectionFactory
      java:/XAConnectionFactory


      Replaced all references to DefaultJMSProvider to RemoteJMSProvider in standardjboss.xml

      Snippet from jbossmq-state.xml: (ON REMOTE MACHINE)

      jason
      foobar
      foo


      foo
      TestsSubscription
      jasonTopic


      Deadly Stack Trace:
      002-08-02 13:55:55,702 INFO [org.jboss.ejb.MessageDrivenContainer] Creating
      2002-08-02 13:55:55,702 DEBUG [org.jboss.ejb.MessageDrivenContainer] Mapped onMessage 1175993645 to public void jbossmqejb.MyTextMDB.onMessage(javax.jms.Message)
      2002-08-02 13:55:55,702 INFO [org.jboss.ejb.plugins.MessageDrivenInstancePool] Creating
      2002-08-02 13:55:55,702 INFO [org.jboss.ejb.plugins.MessageDrivenInstancePool] Created
      2002-08-02 13:55:55,702 INFO [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Creating
      2002-08-02 13:55:55,712 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Initializing
      2002-08-02 13:55:55,712 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Looking up provider adapter: java:/RemoteJMSProvider
      2002-08-02 13:55:55,712 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Provider adapter: org.jboss.jms.jndi.JBossMQProvider@62ecc7
      2002-08-02 13:55:55,712 INFO [org.jboss.ejb.plugins.jms.DLQHandler] Creating
      2002-08-02 13:55:55,712 DEBUG [org.jboss.jms.jndi.JBossMQProvider] connecting to remote JNDI with props: {java.naming.provider.url=gram:1099, java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.rmi.security.manager=yes, java.naming.factory.url.pkgs=org.jboss.naming}
      2002-08-02 13:55:55,712 DEBUG [org.jboss.jms.jndi.JBossMQProvider] created context: javax.naming.InitialContext@a1977
      2002-08-02 13:55:55,712 DEBUG [org.jboss.ejb.plugins.jms.DLQHandler] Using factory: org.jboss.mq.SpyXAConnectionFactory@22ce00
      2002-08-02 13:55:55,712 DEBUG [org.jboss.mq.GenericConnectionFactory] Handing out ClientIL: org.jboss.mq.il.jvm.JVMClientILService
      2002-08-02 13:55:55,712 DEBUG [org.jboss.ejb.plugins.jms.DLQHandler] Created connection: org.jboss.mq.SpyConnection@de972
      2002-08-02 13:55:55,732 DEBUG [org.jboss.mq.referenceable.SpyDestinationObjectFactory] SpyDestinationObjectFactory->getObjectInstance()
      2002-08-02 13:55:55,732 DEBUG [org.jboss.ejb.plugins.jms.DLQHandler] Using Queue: QUEUE.DLQ
      2002-08-02 13:55:55,732 INFO [org.jboss.ejb.plugins.jms.DLQHandler] Created
      2002-08-02 13:55:55,732 DEBUG [org.jboss.jms.jndi.JBossMQProvider] connecting to remote JNDI with props: {java.naming.provider.url=gram:1099, java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.rmi.security.manager=yes, java.naming.factory.url.pkgs=org.jboss.naming}
      2002-08-02 13:55:55,742 DEBUG [org.jboss.jms.jndi.JBossMQProvider] created context: javax.naming.InitialContext@2826da
      2002-08-02 13:55:55,742 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] context: javax.naming.InitialContext@2826da
      2002-08-02 13:55:55,742 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] jndiSuffix: jasonTopic
      2002-08-02 13:55:55,742 DEBUG [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Got destination type Topic for MyTextMDB
      2002-08-02 13:55:55,742 DEBUG [org.jboss.jms.ConnectionFactoryHelper] using connection factory: org.jboss.mq.SpyXAConnectionFactory@22ce00
      2002-08-02 13:55:55,742 DEBUG [org.jboss.jms.ConnectionFactoryHelper] using username/password: jason/foobar
      2002-08-02 13:55:55,742 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.parentTraceEnabled=true
      2002-08-02 13:55:55,752 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.nestedTraceEnabled=true
      2002-08-02 13:55:55,752 DEBUG [org.jboss.util.NestedThrowable] org.jboss.util.NestedThrowable.detectDuplicateNesting=true
      2002-08-02 13:55:55,752 INFO [org.jboss.ejb.plugins.jms.JMSContainerInvoker] Created
      2002-08-02 13:55:55,752 INFO [org.jboss.ejb.MessageDrivenContainer] Created
      2002-08-02 13:55:55,752 WARN [org.jboss.ejb.plugins.jms.JMSContainerInvoker] JMS provider failure detected:
      org.jboss.mq.SpyJMSException: Cannot get a client ID; - nested throwable: (javax.jms.JMSSecurityException: The login id has an assigned client id. That client id is already connected to the server!)
      at org.jboss.mq.Connection.askForAnID(Connection.java:749)
      at org.jboss.mq.Connection.(Connection.java:237)
      at org.jboss.mq.SpyConnection.(SpyConnection.java:48)
      at org.jboss.mq.SpyXAConnection.(SpyXAConnection.java:38)
      at org.jboss.mq.SpyXAConnectionFactory.createXATopicConnection(SpyXAConnectionFactory.java:97)
      at org.jboss.jms.ConnectionFactoryHelper.createTopicConnection(ConnectionFactoryHelper.java:146)
      at org.jboss.ejb.plugins.jms.JMSContainerInvoker.innerCreate(JMSContainerInvoker.java:470)
      at org.jboss.ejb.plugins.jms.JMSContainerInvoker.createService(JMSContainerInvoker.java:374)
      at org.jboss.system.ServiceMBeanSupport.create(ServiceMBeanSupport.java:168)
      at org.jboss.ejb.MessageDrivenContainer.createService(MessageDrivenContainer.java:157)
      at org.jboss.system.ServiceMBeanSupport.create(ServiceMBeanSupport.java:168)
      at org.jboss.ejb.Container.invoke(Container.java:719)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:549)
      at com.sun.jdmk.comm.HtmlInvokePage.buildPage(HtmlInvokePage.java:243)
      at com.sun.jdmk.comm.HtmlRequestHandler.processGetRequest(HtmlRequestHandler.java:329)
      at com.sun.jdmk.comm.HtmlRequestHandler.processRequest(HtmlRequestHandler.java:155)
      at com.sun.jdmk.comm.HtmlRequestHandler.doRun(HtmlRequestHandler.java:82)
      at com.sun.jdmk.comm.ClientHandler.run(ClientHandler.java:88)
      at java.lang.Thread.run(Thread.java:484)
      + nested throwable:
      javax.jms.JMSSecurityException: The login id has an assigned client id. That client id is already connected to the server!

      Again, it is an MDB in one instance of JBoss attepting to listen to a durable topic on another instance of JBoss.

      Any 3.0 help would greatly be appreciated.

        • 1. Re: MDB durable subscriber

          Hi, here are a couple of things to remember:

          1. If you connect a clientid to a user/password in jbossmq-state, that user can only ever hold on to one durable subscription. If you let this user login multple times, durable subs will NOT work.

          2. The prefarable aproach is to connect a clientid to the user dynamically. For MDB this is done by using the mcd-client-id elemtent in the deployment descriptor.

          3. The easiest way to get a durable sub then is NOT to edit the jbossmq-state by hand, but to deploy the MDB. After that, the durable sub will be set up automatically (look in jbossmq-state after the deploy).

          Hope this helps.

          //Peter

          • 2. Re: MDB durable subscriber
            jweis

            Thanks for the reply, but I have had no success with this. I did all that you suggested and got the same result. I even tried creating a new user in jboss-mqstate whom could not possibly already be logged on, but the same message about already being logged on comes back. I have seen similar posts complaining of the same types of problems, but no one seems to have a solution. I am ready to call this a problem with JBoss 3.0 until someone can show me or tell me they have a MDB running on one instance of Jboss as a durable subscriber listening to a topic on another instance of Jboss.