Configuring multiplex Clients and callback Connectors
ron_sigal May 31, 2006 3:28 AMI would like to respond in the public forum to an issue expressed in the following e-mail from Michael Voß . It concerns the configuration of a Client and callback Connector using the sslmultiplex transport.
> I have discovered another problem but I am not sure if it is about Linux/Windows differences or the cpu speed or sth. else:
> Regarding the client:
>
> On a Unix system I first build up the client object and run connect() and then build up and start the connector so that the program works fine.
> The other way round I get the exception: java.lang.InvocationTargetException ... caused by java.lang.RuntimeException: Address already in use when adding a callback listener to the client object
> + also getting Exception in thread "Timer-2" java.lang.NullPointerException
>
> Running the client application in Windows I need to build up and run the connector object first and then the client object to run properly
> The other way round I get the exception: java.lang.InvocationTargetException ... caused by java.lang.RuntimeException: Connection refused by Client client = new Client(locator, "subsys", configuration);
>
>
> I use sslmultiplex
> How already mentioned I do not know the cause for this but I can not imagine that it is about Windows or Unix
>
> What do you think about it?
>
The multiplex and sslmultiplex transports have been in flux recently (as has been much of Remoting), and the primary solution is to use the newest version. With CVS version JBossRemoting_2_0_0_beta_2 I was able to get Michael's example to work, in all of its variations, with only a single code modification (other than a change of ports), and I want to talk about that modification because it concerns the admittedly complicated invoker group rules.
Michael creates a Connector with InvokerLocator, say, sslmultiplex://localhost:2001, and then creates, in some order, a Client and a callback Connector. Simplifying somewhat, suppose the Client is set up so:
configuration.put(Multiplex.MULTIPLEX_BIND_HOST, "localhost"); configuration.put(Multiplex.MULTIPLEX_BIND_PORT, "3001"); client = new Client("sslmultiplex://localhost:2001", configuration); client.connect();
and then the Connector is set up so:
connector = new Connector("sslmultiplex://localhost:3001", configuration); connector.create(); SSLMultiplexServerInvoker invoker=(SSLMultiplexServerInvoker)connector.getServerInvoker(); invoker.setClientConnectAddress("localhost"); invoker.setClientConnectPort(2001); connector.start();
The result of starting the callback Connector will be: java.net.BindException: Address already in use.
The reason is that the InvokerLocator "sslmultiplex://localhost:3001" gives MultiplexServerInvoker no clue that it is meant to share a connection with a MultiplexClientInvoker. In the absence of any hint to the contrary, it will create, during the call to Connector.create(), a "real" server socket, i.e., MasterServerSocket, instead of a VirtualServerSocket, and try to bind it to port 3001. This behavior is determined by server rule 4.
One solution is to rewrite the callback Connector code as follows:
configuration.put(Multiplex.MULTIPLEX_CONNECT_HOST, "localhost"); configuration.put(Multiplex.MULTIPLEX_CONNECT_PORT, "2001"); connector = new Connector("sslmultiplex://localhost:3001", configuration); connector.create(); connector.start();
The presence of the "connect" information tells MultiplexServerInvoker to look for an existing invoker group to join, and it will create a VirtualServerSocket that uses the real socket bound to port 3001.
This example suggests that it might be reasonable to change the invoker group rules so that a MultiplexServerInvoker will try to create VirtualServerSocket bound to a given port if it finds that port in use. It's something to think about.