5 Replies Latest reply on Dec 6, 2006 11:31 PM by ron_sigal

    InvokerLocator already exists for listener

    dunks80

      Sory to cross post (I also posted in the messaging forum) but this seems like it may deal more with remoting.

      I'm using Jboss 4.0.5 and JBoss Messaging 1.0.1.

      What is happening is that I'm looping through a list of items and sending each item in the list off to a queue that has an MDB listening on it. I get maybe half way through the list and then this exception occurs. The code worked fine with JbossMQ but when I switched to JBoss messaging this started happening.

      I'm sending alot of small messages very quickly. Is there somthing I have to set with the connector so this exception does not occur?

      javax.jms.IllegalStateException: InvokerLocator already exists for listener id 1436420135. Remove t
      his listener before adding again.
       at org.jboss.jms.client.container.ExceptionInterceptor.invoke(ExceptionInterceptor.java:91)
       at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate$createConnectionDelegate_N6
      840474864420126404.invokeNext()Ljava.lang.Object;(ClientConnectionFactoryDelegate$createConnectionDe
      legate_N6840474864420126404.java:???)
       at org.jboss.jms.client.container.ClientLogInterceptor.invoke(ClientLogInterceptor.java:107)
      
       at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate$createConnectionDelegate_N6
      840474864420126404.invokeNext()Ljava.lang.Object;(ClientConnectionFactoryDelegate$createConnectionDe
      legate_N6840474864420126404.java:???)
       at org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate.createConnectionDelegate(Lj
      ava.lang.String;Ljava.lang.String;)Lorg.jboss.jms.delegate.ConnectionDelegate;(ClientConnectionFacto
      ryDelegate.java:???)
       at org.jboss.jms.client.JBossConnectionFactory.createConnectionInternal(JBossConnectionFacto
      ry.java:202)
       at org.jboss.jms.client.JBossConnectionFactory.createQueueConnection(JBossConnectionFactory.
      java:108)
       at org.jboss.jms.client.JBossConnectionFactory.createQueueConnection(JBossConnectionFactory.
      java:103)
      ...
      
      


        • 1. Re: InvokerLocator already exists for listener
          dunks80

          Well i think I found the problem...

          In org.jboss.remoting.Client the createListenerMetadata uses the callbackHandlers hashCode to create the listenerId which is later used to in the AbstractInvokerLocator to detemine whether a listener already has a clientLocator registered for it.

          Client

           private Map createListenerMetadata(InvokerCallbackHandler callbackHandler)
           {
           String listenerId = String.valueOf(callbackHandler.hashCode());
           Map metadata = new HashMap();
           metadata.put(LISTENER_ID_KEY, listenerId);
           return metadata;
           }
          

          AbstractInvoker
          /**
           * Sets the callback server locator for the specified callback listener id
           *
           * @param locator
           */
           public void addClientLocator(String listenerId, InvokerLocator locator)
           {
           Object obj = localServerLocators.put(listenerId, locator);
           if(obj != null)
           {
           throw new RuntimeException("InvokerLocator already exists for listener id " + listenerId + ". " +
           "Remove this listener before adding again.");
           }
           }
          


          I was using JRockit 64-bit jdk for linux (R26.4.0-jdk1.5.0.6). I switched over to the normal Sun jdk and the problem magically went away. I'm not sure if this is a problem with the way JRockit handles hashcodes or if it's a problem with using the hashcode of the callbackHandler as the listenerId.

          • 2. Re: InvokerLocator already exists for listener
            timfox

            I'd say this was a bug in remoting since hashCode's don't have to be unique.

            I.e. it's quite possible that 2 different callback handler's might return the same hashcode.

            • 3. Re: InvokerLocator already exists for listener
              dunks80

              Just for more info the callbackHandler in question is coming from org.jboss.jms.client.remoting.JMSRemotingConnection

              public JMSRemotingConnection(String serverLocatorURI, boolean clientPing) throws Throwable
               {
               serverLocator = new InvokerLocator(serverLocatorURI);
               this.clientPing = clientPing;
               dummyCallbackHandler = new DummyCallbackHandler();
              
               log.debug(this + " created");
               }
              

              and is later used...

              public void start() throws Throwable
               {
               ...
               // We add a dummy callback handler only to trigger the addListener method on the
               // JMSServerInvocationHandler to be called, which allows the server to get hold of a reference
               // to the callback client so it can make callbacks
              
               client.addListener(dummyCallbackHandler, callbackServer.getLocator());
               ...
               }
              


              • 4. Re: InvokerLocator already exists for listener

                Jira issue - http://jira.jboss.com/jira/browse/JBREM-622

                Following describes behavior due to code changes for this issue:

                Behavior - If doing pull callbacks, can have same callback handler registered with two remoting Client instances (i.e. A and B) and the server will see this as two distinct callback listeners being registered. So if server generates a callback, both Client instance will retreive a callback.

                If doing push callbacks, meaning have a callback server registered to receive callbacks, the callbacks will be tied to that callback server and its callback handler. Therefore, if have callback handler and server registered, only one callback will be delivered per one generated on target server, regardless of with how many remoting Clients they have been registered as listeners with. An example would be have remoting Client A and B, and have callback handler X and callback server Y. If registered callback handler X and callback server Y with both A and B and the server generates a callback message, it will only be delivered once to callback handler X.

                If have the same callback handler registered with multiple callback server, a callback message will be delivered for each callback server. For example, if have callback handler X and callback server Y and Z and then register callback handler X twixe (once with Y and once with Z), then will be delivered the same callback message twice (once by Y and once by Z).

                When a callback handler is removed and are using push callbacks, the callback handler will be removed as a listener from all callback servers it has been registered under.
                [ Show » ]
                Tom Elrod [09/Nov/06 03:48 PM] Behavior - If doing pull callbacks, can have same callback handler registered with two remoting Client instances (i.e. A and B) and the server will see this as two distinct callback listeners being registered. So if server generates a callback, both Client instance will retreive a callback. If doing push callbacks, meaning have a callback server registered to receive callbacks, the callbacks will be tied to that callback server and its callback handler. Therefore, if have callback handler and server registered, only one callback will be delivered per one generated on target server, regardless of with how many remoting Clients they have been registered as listeners with. An example would be have remoting Client A and B, and have callback handler X and callback server Y. If registered callback handler X and callback server Y with both A and B and the server generates a callback message, it will only be delivered once to callback handler X. If have the same callback handler registered with multiple callback server, a callback message will be delivered for each callback server. For example, if have callback handler X and callback server Y and Z and then register callback handler X twixe (once with Y and once with Z), then will be delivered the same callback message twice (once by Y and once by Z). When a callback handler is removed and are using push callbacks, the callback handler will be removed as a listener from all callback servers it has been registered under.

                • 5. Re: InvokerLocator already exists for listener
                  ron_sigal

                  The following change has been made to the behavior of reused InvokerCallbackHandlers:

                  ServerInvoker stores the client side InvokerCallbackHandler using a key consisting of the sessionId of the Client that is registering the InvokerCallbackHandler concatenated with the InvokerCallbackHandler's listenerId. When ServerInvoker is asked to unregister a client side InvokerCallbackHandler X, it looks for X based on the sessionId of the Client making the request concatenated with the listenerId of X. When a Client other than the one that registered InvokerCallbackHandler X tries to unregister X, the ServerInvoker can't find X. It follows that a Client can unregister only those InvokerCallbackHandlers that it has registered.