You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by davidmc <ar...@gmail.com> on 2007/04/20 10:27:50 UTC

Bug when setting transportConnector URI options in activemq.xml

Hello folks,

As you may know, there are some problems when setting options in the URI for
a transportConnector in the broker configuration file activemq.xml (at least
for me when launching the console with the Main class and the start
command).
For example, the option 'socket.tcpNoDelay=true' works fine in a producer or
consumer URI, but doesn't make the broker have TCP_NODELAY sockets when it
is set in the activemq.xml file.

I think I have this more or less nailed down, I will try to explain.
During all my explanation, I'm using the last source from SVN at the time of
writing.

Let's imagine you have the following piece of xml in your activemq.xml file:

    <transportConnectors>
      <transportConnector
uri="tcp://localhost:61616?trace=true&amp;foo=bar"/>
    </transportConnectors>

(side note: i have not found in the documentation the need to use ' & a m p
;' in this file, instead of just '&' like in Java code, would be a nice
addition for clueless people like myself)
(side note 2: in the forum the & a m p ; appears as just &, but you have to
write '& a m p ;' without the spaces of course).

How do these options get processed? Well at some point the method
'org.apache.activemq.transport.tcp.TcpTransportFactory.doBind' gets
executed.

    public TransportServer doBind(String brokerId, final URI location)
throws IOException {
        try {
            Map options = new HashMap(URISupport.parseParamters(location));

We now have a nice HashMap with our options: {trace=true, foo=bar}

            ServerSocketFactory serverSocketFactory =
createServerSocketFactory();
            TcpTransportServer server = createTcpTransportServer(location,
serverSocketFactory);
            server.setWireFormatFactory(createWireFormatFactory(options));
            IntrospectionSupport.setProperties(server, options);

'IntrospectionSupport.setProperties' is a method who uses reflexion to find
the setter methods of a class, and if there is a setter method with the same
name as a key of our HashMap, sets the value.
The 'doBind' method finishes wish

            Map transportOptions =
IntrospectionSupport.extractProperties(options, "transport.");
            server.setTransportOption(transportOptions);
            server.bind();
            
            return server;
        }
        catch (URISyntaxException e) {
            throw IOExceptionSupport.create(e);
        }
    }

This is what happens when you start the broker.
Now, what happens when a client connects and the broker has to create a
Transport object for the connection?
The method org.apache.activemq.transport.tcp.TcpTransportServer.run() gets
executed:

    [some irrelevant stuff]
                        HashMap options = new HashMap();
                        options.put("maxInactivityDuration", new
Long(maxInactivityDuration));
                        options.put("minmumWireFormatVersion", new
Integer(minmumWireFormatVersion));
                        options.put("trace", new Boolean(trace));
                        options.putAll(transportOptions);
                        WireFormat format =
wireFormatFactory.createWireFormat();
                        Transport transport = createTransport(socket,
format);
                        Transport configuredTransport =
transportFactory.serverConfigure(transport, format, options);
                        getAcceptListener().onAccept(configuredTransport);
    [more irrelevant stuff]

As you see this method constructs a new HashMap options object, which is
used to configure the Transport with the line:
                        Transport configuredTransport =
transportFactory.serverConfigure(transport, format, options);
If you have a look at this method, you will see that after a call to another
method, the properties of the Transport are set again with
'IntrospectionSupport.setProperties'.

So what's the problem? The problem is that for the properties to be
recognized, they have to be declared as setters in 2 classes. In this case,
TcpTransport and TcpTransportServer.
When a property is set in the connection URI of a client, the ActiveMQ
classes don't use TcpTransportServer. They directly set the options on the
TcpTransport.
However in a broker, the execution path goes through the TcpTransportServer
class. If the options don't have setters declared, and are not later put
into the 'options' object in the The method
'org.apache.activemq.transport.tcp.TcpTransportServer.run()' method, the
Transport created by the broker does not have these options set.

If you have a look at the TcpTransportServer class, you will see that the
only options accepted are:
-maxInactivityDuration
-minmumWireFormatVersion (small mispelling btw)
-trace
-transport.* options

Furthermore, the way things work, if you put another option on the URI, it
will be silently ignored. You can put 'foo=bar' or 'socket.tcpNoDelay=true'
and no error message appears. So people may have been using options and
thinking they had no effect, where in fact they were ignored without
warning, like in the TCP_NODELAY case.

I don't know how the ActiveMQ devs want to design this class, but I see 2
solutions:
-manually add the missing options to TcpTransportServer, and update the docs
so that they are synchronized with the actual options that have to be used
(like socket.tcpNoDelay=true instead of wireFormat.tcpNoDelayEnabled=true).
-somehow eliminate the double IntrospectionSupport.setProperties usage, and
pass the options directly to the TcpTransport class. This will save the need
to remember to put options in 2 classes every time one is added. And of
course, there is still the need to keep the docs synchronized... :)

If you want to reproduce my analysis, I used Eclipse, executing ActiveMQ
source using the console Main class, in debug mode, and using breakpoints in
the methods above mentioned.

Hope this helps :)

David
-- 
View this message in context: http://www.nabble.com/Bug-when-setting-transportConnector-URI-options-in-activemq.xml-tf3611737s2354.html#a10093006
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.


Re: Bug when setting transportConnector URI options in activemq.xml

Posted by davidmc <ar...@gmail.com>.
Made a JIRA for this:
https://issues.apache.org/activemq/browse/AMQ-1233
I mostly copied this message but there are a couple corrections.
-- 
View this message in context: http://www.nabble.com/Bug-when-setting-transportConnector-URI-options-in-activemq.xml-tf3611737s2354.html#a10094059
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.