-
1. Re: InvokerLocator already exists for listener
dunks80 Oct 26, 2006 7:16 AM (in response to 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.
Clientprivate 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 Oct 26, 2006 7:59 AM (in response to dunks80)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 Oct 26, 2006 8:17 AM (in response to 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
tom.elrod Nov 9, 2006 3:49 PM (in response to dunks80)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 Dec 6, 2006 11:31 PM (in response to dunks80)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.