activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Martín Clavo (JIRA) <>
Subject [jira] Commented: (AMQ-1233) Bug when setting transportConnector URI options in activemq.xml
Date Wed, 13 Jun 2007 08:02:34 GMT


David Martín Clavo commented on AMQ-1233:

Also, I think this bug / problem should be given a higher priority, since it affects the ActiveMQ-CPP
ActiveMQ-CPP was recently updated so that the c++ client's sockets could have TCP_NODELAY
set to true.
But that's not 100% useful if the ActiveMQ broker's sockets cannot have TCP_NODELAY set to
true (unless you hack the code to make all sockets have TCP_NODELAY=true).
In my description, I already describe where I think the problem i. I don't want to write a
patch myself since it would imply changing the insides of the code and I don't know how you
guys would like it to be done.

Just my 2 cents...


> Bug when setting transportConnector URI options in activemq.xml
> ---------------------------------------------------------------
>                 Key: AMQ-1233
>                 URL:
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.x
>            Reporter: David Martín Clavo
> 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
> 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&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 gets executed:
>     [some 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 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 '' method, the Transport
created by the broker does not have these options set.
> In our example, trace=true will be recognized but not foo=bar.
> 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.

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message