Monit alerts sent from a Dreamhost email account

This little snippet of configuration took way to long to figure out so I’m sharing it in hopes of saving others the trouble. If you are using monit and trying to send alerts from a Dreamhost email account you will need to use the following settings.

set mailserver mail.your.host.name port 465
username "monit@your.host.name"
password "password"
using SSLV3
with timeout 15 seconds
set alert alerts@your.host.name
with mail-format { from: monit@your.host.name }

It turns out that monit and Dreamhost don’t get along on the default port 587. The solution according to Dreamhost is to use port 465. This works as long as you use SSLv3 instead of TLSv1. The other important part of this configuration is making sure you set the from address in your mail format. Otherwise monit tries to send from monit@<hostname> which in most cases is not a fully qualified name and will cause Dreamhost to fail.

ConnectionFactories and Caching with Spring and ActiveMQ

© Sean Ryan

In my previous two posts on ActiveMQ and Spring I’ve shown how to implement both asynchronous and synchronous messaging using MessageListenerContainers and JmsTemplates. Since then I have continued to tweak and improve my use of Spring’s JMS support and have uncovered a few more details about the ConnectionFactories supplied by both ActiveMQ and Spring and how they play together nicely and not so nicely. Some of this info is new while some was covered in my second post and lead to an edit in my initial post but I will reiterate that information here to keep it all in one place.

PooledConnectionFactory

This bad boy is the ActiveMQ provide connection pooler. It pools connections, sessions and producers and does a fine job of it. There is nothing particularly wrong with this connection factory though it does strike me as odd that it caches connections since, according to the JMS spec, connections support concurrent use.

SingleConnectionFactory

It might seem odd to have a connection factory that ensures only one connection but in reality this is quite useful. When using multiple JmsTemplates and MessageListenerContainers in Spring they will end up each creating their own connection since the default ConnectionFactory will create a new connection for each createConnection() call. Initially I thought this would be fine but I ran into some very weird issues where producers and consumers couldn’t see each other. I’m not sure if this had something to do with using embedded brokers and the VM Transport but it wasn’t good. Using a SingleConnectionFactory as the initial decorator around the default ConnectionFactory solved these issues.

CachingConnectionFactory

This is the real heavy lifter. It will cache sessions and can optionally cache consumers and producers. As any post on JmsTemplate will tell you, you MUST use caching for any sort of reasonable performance if you are not running in a JCA container. As such, this is the factory to use when using a JmsTemplate. A few points should be made clear though. First, the default is for only one session to be cached. The javadoc claims this is sufficient for low concurrency but if you are doing something more high end you probably want to increase the SessionCacheSize. Additionally, there is some weirdness around cached consumers. They don’t get closed until they are removed from the pool and they are cached using a key that contains the destination and the selector. This lead to essentially a memory leak when trying to use cached consumers for request response semantics using JMSCorrelationIds. In general caching consumers is hard which is why MessageListenerContainers should be used instead.

How’s it all work

<amq:connectionFactory id="connectionFactory" brokerURL="${jms.url}"/>
<bean id="singleConnectionFactory" p:targetConnectionFactory-ref="connectionFactory" p:reconnectOnException="true"/>
<bean id="cachingConnectionFactory" p:targetConnectionFactory-ref="singleConnectionFactory" p:sessionCacheSize="100"/>
<bean id="jmsTemplate" p:connectionFactory-ref="cachingConnectionFactory"/>
<jms:listener-container connection-factory="singleConnectionFactory">
<jms:listener id="QueueHandler" destination="Queue" ref="queueHandler"/>
</jms:listener-container>

First we start with a basic ActiveMQ ConnectionFactory. From there we wrap it in a SingleConnectionFactory and then wrap that in a CachingConnectionFactory. I’ve increased the SessionCacheSize on the CachingConnectionFactory to 100, this might be overkill but my application is anything but memory hungry so I figured I could err on the side of too many sessions. Additionally, and this is important, ReconnectOnException is set to true on the SingleConnectionFactory. The CachingConnectionFactory requires this and will complain loudly but in such as way as to make it unclear what is going on if this is not set. From there we use the CachingConnectionFactory to create a JmsTemplate and we use the SingleConnectionFactory to create a MessageListenerContainer since it takes care of any caching of sessions and consumers that it needs.

ActiveRecord Naming Conventions with Spring JDBC

java ruby on railsOne of the best choices we made at my current job was splitting the web development from the heavy message processing system, allowing the former to be written in Ruby on Rails and the latter to be written in Java. However, for ease of development, we allowed the two code bases share a single database. What then to do about database naming conventions? Those familiar with ActiveRecord will know that it is very particular about its database naming conventions so it was up to the Java code to play nicely. The first solution to present itself required hardcoding database names in each Java object but a more elegant solution seemed possible and, after the discovery of one small but important 3rd party project, it revealed itself.

Inflection

In Rails, the class responsible for converting object names to database names is called Inflections. For those unfamiliar with the term (as I was), inflection is the modification of a word to express different grammatical categories. Armed with this new knowledge I set about googling and was relieved to find that Tom White had already implemented a Java Inflector. However, the Java Inflector only implements the pluralization aspect of the Rails Inflections; for this to work I was going to need some additional string manipulation tools. Luckily the old Apache Commons StringUtils was there to lend a helping hand. Finally, confident in my string manipulation tools, the next step was to look into the JDBC side of things.

ORMs

When dealing with mapping objects to and from a database Hibernate is always the name that pops up. I’ve worked with it in the past and, while incredibly powerful, I always felt like I was wielding a hatchet when what I wanted was a surgical knife. I’ve heard its configuration has been simplified with JPA but its still a beast of a project that relies on a bit more magic than I’m comfortable with. In a more recent project I played with iBatis (now myBatis) and enjoyed the simplicity but felt overwhelmed by the xml configuration. Version 3.0 supports annotation configuration which greatly simplifies this but I was looking for something based on naming conventions so I wouldn’t have to supply the mapping myself. I don’t mind getting down and dirty with some SQL so I opted for Spring JDBC. Spring provides a super thin layer on top of raw JDBC which takes what is a fairly developer hostile API and makes it a breeze to use, all while adding some wonderful utilities to speed development.

Putting It All Together

AbstractDbObj

The first step was to create an AbstractDbObj to allow all other database objects to inherit from. This is where the logic for creating db names using the Inflector and StringUtils lives along with some other shared code.

import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
import static org.apache.commons.lang.StringUtils.join;
import static org.apache.commons.lang.StringUtils.lowerCase;
import static org.apache.commons.lang.StringUtils.splitByCharacterTypeCamelCase;
import static org.jvnet.inflector.Noun.pluralOf;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;

public abstract class AbstractDbObj  implements DbObj {
  private static final String[] EXCLUDED_FIELD_NAMES = new String[] { "columnNames", "map", "fieldNames", "tableName" };
  private static final Predicate<String> IS_COLUMN = new Predicate<String>() {
    private final ImmutableSet<String> notColumns = ImmutableSet.of( "class", "tableName", "columnNames", "fieldNames" );
    public boolean apply( final String propName ) {
      return !notColumns.contains( propName );
    }
  };

  private static final ConcurrentMap<Class<? extends LocaDbObj>, String> TABLE_NAME_LOOKUP = new ConcurrentHashMap<Class<? extends LocaDbObj>, String>();

  private static final Function<String, String> TO_COLUMN = new Function<String, String>() {
    public String apply( final String fieldName ) {
      return underscore( fieldName );
    }
  };

  private static String tableName( final Class<? extends LocaDbObj> clazz ) {
    return pluralOf( underscore( clazz.getSimpleName() ) );
  }

  protected static String underscore( final String camelCasedWord ) {
    return lowerCase( join( splitByCharacterTypeCamelCase( camelCasedWord ), '_' ) );
  }

  private Integer id;
  private final Collection<String> fieldNames;
  private final String tableName;
  private final Map<String, Object> map;
  private final Collection<String> columnNames;

  @SuppressWarnings( "unchecked" )
  protected AbstractLocaDbObj() {
    super();
    final Class<? extends LocaDbObj> clazz = getClass();
    String tblName = TABLE_NAME_LOOKUP.get( clazz );
    if ( tblName == null ) {
      tblName = tableName( clazz );
      TABLE_NAME_LOOKUP.put( clazz, tblName );
    }
    tableName = tblName;
    final BeanMap beanMap = new BeanMap( this );
    fieldNames = filter( beanMap.keySet(), IS_COLUMN );
    columnNames = transform( fieldNames, TO_COLUMN );
    map = beanMap;
}

  @SuppressWarnings( "unchecked" )
  protected AbstractLocaDbObj( final String tableName ) {
    super();
    this.tableName = tableName;
    final BeanMap beanMap = new BeanMap( this );
    fieldNames = filter( beanMap.keySet(), IS_COLUMN );
    columnNames = transform( fieldNames, TO_COLUMN );
    map = beanMap;
  }

  @Override
  public boolean equals( final Object obj ) {
    return EqualsBuilder.reflectionEquals( this, obj, EXCLUDED_FIELD_NAMES );
  }

  public String getColumnName( final String fieldName ) {
    return underscore( fieldName );
  }

  public Collection<String> getColumnNames() {
    return columnNames;
  }

  public Collection<String> getFieldNames() {
    return fieldNames;
  }

  public Integer getId() {
    return id;
  }

  public String getTableName() {
    return tableName;
  }

  @Override
  public int hashCode() {
    return HashCodeBuilder.reflectionHashCode( this, EXCLUDED_FIELD_NAMES );
  }

  public void setId( final Integer id ) {
    this.id = id;
  }

  public Map<String, Object> toMap() {
    return map;
  }

  @Override
  public String toString() {
    return new ReflectionToStringBuilder( this ).setExcludeFieldNames(EXCLUDED_FIELD_NAMES ).toString();
  }
}

A few things to point out. First, I’m making use of the Google Collections Function and Predicate. For more info on that check out the developer.com article. Second, I’m using Apache BeanUtils BeanMap which uses reflection to easily create a property to value map of a JavaBean. Finally, I’m storing the table names in a lookup since the pluralization a very expensive operation. The rest should hopefully be somewhat straight forward.

SimpleJdbcInsert

Using Spring’s SimpleJdbcInsert, combined with the heavy lifting in the abstract class, insertions are practically free as you can see in the following code.

// Get Datasource from Spring Context
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert( dataSource ).withTableName( dbObj.getTableName() ).usingGeneratedKeyColumns( "id" );
final int id = jdbcInsert.executeAndReturnKey( new BeanPropertySqlParameterSource( dbObj ) ).intValue();
dbObj.setId( id );

Note: you can reuse a SimpleJdbcInsert since it is thread safe, I created a new one in the above code just to show how it is done.

SimpleJdbcTemplate

After inserts, the other two pieces of required functionality are query and update, both of which are supplied by Spring’s SimpleJdbcTemplate. The trick here is to make generous use of Spring’s BeanPropertySqlParameterSource and BeanPropertyRowManager which effortlessly map between JavaBean properties and database columns.

Lets start with the simple case of deleting an object.


simpleJdbcTemplate.update( "DELETE FROM " + dbObj.getTableName() + " WHERE id = :id", new BeanPropertySqlParameterSource( dbObj ) );

You’ll notice the string “id = :id” in the query. This allows Spring to do value substitution, using the BeanPropertySqlParameterSource to replace :id with the actual value of .getId() from the dbObj. With this in mind we can step up to the more complicated update case.

final Collection<String> parts = buildUpdateParts( dbObj );
if ( parts.isEmpty() ) { return; }
final String query = "UPDATE " + dbObj.getTableName() + " SET " + join( parts, ", " ) + " WHERE id = :id";
simpleJdbcTemplate.update( query, new BeanPropertySqlParameterSource( dbObj ) );
private static final Collection<String> buildUpdateParts( final LocaDbObj dbObj ) {
  return transform( filter( dbObj.getFieldNames(), not( IS_ID ) ), new BuildPart( dbObj ) );
}
private static final class BuildPart implements Function<String, String> {
  private final LocaDbObj dbObj;
  public BuildPart( final LocaDbObj dbObj ) {
    this.dbObj = dbObj;
  }
  public String apply( final String propName ) {
    return dbObj.getColumnName( propName ) + " = :" + propName;
  }
}

This code again makes use of google collections but the point is that it takes the field names and the column names from the DbObj and creates snips of sql setting the column name to the field name identifier (i.e. the field name prefixed with ‘:’) just like was done in the deletion case with “id = :id”. Continuing to build on the previous examples we finally come to the query case. This one is a bit difference since we are interested in reading results from the database as well as building a query so we will have to deal with the BeanPropertyRowMapper.

final Collection<String> parts = buildQueryParts( dbObj );
if ( parts.isEmpty() ) { return ImmutableList.of(); }
final String query = "SELECT " + columnNames + " FROM " + dbObj.getTableName() + " WHERE " + join( parts, " AND " );
return result = simpleJdbcTemplate.query( query, new BeanPropertyRowMapper<DbObj>( dbObj.getClass() ), new BeanPropertySqlParameterSource( dbObj ) );
private static final Collection<String> buildQueryParts( final LocaDbObj dbObj ) {
  return transform( filter( dbObj.getFieldNames(), new HasValue( dbObj.toMap() ) ), new BuildPart( dbObj ) );
}
private static final class HasValue implements Predicate<String> {
  private final Map<String, Object> map;
  public HasValue( final Map<String, Object> map ) {
    this.map = map;
  }
  public boolean apply( final String propName ) {
    return map.get( propName ) != null;
  }
}

Hopefully by this point the google collections syntax is becoming familiar. We want to include only object fields that are non null so we use the HasValue Predicate to check each property by name. From there on the rest is quite similar to the update method where we build parts setting each column name equal to its field name identifier. The only other difference is we use the BeanPropertyRowMapper so Spring can return us a list of the correct type of DbObj.

While certainly a bit heavy on the code I hope this will be useful to those trying to create a simple, straight forward database layer with Spring and ActiveRecord naming conventions. As a bit of a tease, the full code base that this is pulled from contains an genericized DAO object that contains basic annotation driven caching as well as the ability to execute CRUD commands via example objects, ids, sql snippets (i.e. where clauses), or full raw SQL all while keeping things nice and type safe as well as sql injection free using PreparedStatements and value substitution.

Approximating Java Case Objects without Project Lombok

LombokOver the past few months Dick Wall of the Java Posse has been talking up Project Lombok and for good reason. As he points out, its great for reducing boilerplate code in basic Java data objects. However, the more important point that Dick makes is that it prevents stupid errors, particularly when adding new object fields later on in the development cycle. The only unfortunate issue is that Project Lombok requires a compiler hack that can be rather confusing to those not using a supported IDE or for those coding outside of an IDE. However, Apache Commons provides an elegant solution to this issue.

Project Lombok

Lets start with a quick overview of Project Lombok. At its most basic level it provides a set of annotations (i.e. @Data) that you add to your Java data objects. You simply create private fields in an annotated object and the annotation will cause a full set of constructors, getters/setters, equals/hashCode and toString to be generated in the class file at compile time while keeping a simple and minimal source file. Its an elegant solution but it comes with a fair amount of magic surrounding it.

Alternatives

The simple alternative to Project Lombok is to have the IDE generate the code for you. Eclipse, for instance, is very good at doing this with auto generation of constructors, getters/setters, hashCode/equals and toString. This works wonders when creating the object for the first time but, as Dick points out, its too easy to add a new field and forget about updating toString and hashCode/equals leading to confusing and subtle bugs down the road.

The other alternative, and the one I am promoting, strikes a balance between Project Lombok and IDE generation by auto generating the hashCode/equals and toString and leaving the getters/setters and constructors up to the developer as these are necessary for the new field to be of any use.

Apache Commons

Buried deep in the Apache Commons is the builder package containing utilities such as EqualsBuilder, HashCodeBuilder, and ReflectionToStringBuilder. I don’t remember when I first discovered these gems but once I did the lightbulb went off; if used them in an Abstract base class they would ensure proper implementations of equals/hashCode and toString without having to mess with every data object I create.

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public abstract class AbstractBaseObj {

    @Override
    public boolean equals( final Object obj ) {
        return EqualsBuilder.reflectionEquals( this, obj );
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode( this );
    }

    @Override
    public String toString() {
        return new ReflectionToStringBuilder( this).toString();
    }
}

Drawbacks

Of course this option is not with out its own drawbacks compared to Project Lombok. First off, as mentioned before, it does not deal with getters/setters or constructors. However, as I pointed out, I don’t believe this to be a huge imposition since creating a new field without creating getters/setters and/or a constructor using that field is fairly useless. Additionally, I like that this gives ease and flexibility over which constructors are created. This has been quite handy in the most recent project I’ve been working on.

Another draw back is that it requires an Abstract base class from which all objects must inherit. Annotations are certainly a more elegant solution since it doesn’t require a given object hierarchy. However there are often good reasons for a project specific base object for reasons beyond just equals/hashCode and toString. Additionally, the base class is fully owned by the project with just the few methods necessary being implemented. This is significantly better than having to inherit from a class provided by some 3rd party jar.

The important drawback, however,  is that the Apache Commons solution uses reflection instead of actually generating code to implement equals/hashCode and toString. Depending on how frequently these are used and how performant they need to be this might be a real consideration to use either Project Lombok or to write all the code directly. However, I have not found this to be the case in my project as it never seems to show up as a hot spot in any profiling I have done.

Typed variables in an untyped world

First, off, I’m a static type person.  Sorry, but I like me some static typing. It makes me feel warm and squishy.  It makes my IDE more useful.  I can refactor an entire code base and go to sleep and not have nightmares.

Moving on, I’ve been using Groovy for unit testing a lot lately and have decided something. I like it. Its really nice to not have to deal with exceptions and be able to create lists and maps inline.  Closures kick butt.  Its really nice and easy. However, the lack of types that enable some of the cool things bug me, but they don’t have to.

Because groovy is a dynamic language you don’t have to provide the type of any given variable. This can be good and bad. Its sometimes convenient when you don’t know or don’t care what the type of a variable is.  However, in most cases, when you do know what the variable type is, it can be helpful to put type the variable.

// untyped, but it is really an ArrayList
def someVariable = ["1","2","3"]

// same idea but now you know the type
List someList = ["1","2","3"]

Now, of course, you could have deduced the type of someVariable given its assignment, but apparently your IDE is not that smart, at least Eclipse isn’t. Especially if its one of my types and not a built in type. One of the main reasons that I type variables is that if you explicitly type them, Eclipse can do auto completion on the method names of your variable.  If you use def to declare your variable Eclipse only gives you the default GroovyObject methods.  Not the best.

Also, providing types with method signatures makes it FAR FAR FAR more obvious what you are expecting of your caller.

Consider a method with the signature:

def someMethod(def thing1, def thing2, def thing3){
...
}

Mmmmmmyeah. I have no idea what to pass to that thing. I also don’t know what its going to give back to me.

Don’t get me wrong, there are times when you don’t know some of these things or its more convenient not to declare them statically, but I have found that if you actually know at compile time what something is going to be, you may want to grease back your hair with your back pocket comb in your black leather jacket and stick it to the man with a quick def, but you from two weeks in the future and the next guy to read your code will be much happier if you throw a few types in there.

Printing Greenhopper Cards From Jira

In an attempt to keep a better historical log of our work, my company switched from a whiteboard and 3×5 cards to Greenhopper on top of JIRA. However, we wanted to keep the whiteboard for ambient information and as a location for morning scrum. Greenhopper doesn’t support a way of printing 3×5 cards so what follows is a very convoluted set of instructions that have gotten up 80% of the way there.

Greasemonkey

Greenhopper has a way of printing story cards but the only available layout is a two column setup that doen’t handle page breaks nicely causing cards to be cut between pages. The following greasemonkey script will force a page break after each card.

function addGlobalStyle(css) {
    var head, style;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}

addGlobalStyle('.issueCard {page-break-after: always;}');

Include this script on the following url pattern:

http://jira.locamoda.com/secure/Print.jspa*

Printing in Firefox

Ideally you could print directly from firefox to the 3×5 card but with my setup (FF 3.6 on OS X 10.6) Firefox wont accept 3×5 as a valid page size. To get around this create a 4.5 x 7.5 paper size by going to File -> Page Setup and select Manage Custom Sizes… under Paper Size. With that paper size selected, navigate to the Planning Board view in Greenhopper and click the printer icon next to your current sprint. Turn off all the headers and footers and click preview, not print.

Printing in Preview

In preview you are able to create a 3×5 paper size. Choose Print from the File menu and you  will see a Paper Size drop down in the print dialog. Select Manage Custom Sizes…, just like in the Page Setup dialog in Firefox, and create a paper size of 3×5. With that paper size selected click the scale radio button and scale up to 125%. Finally, load your printer with 3×5 cards and click print. You should end up with prints that fill most of a 3×5 card.

Synchronous Request Response with ActiveMQ and Spring

activemq-5-x-box-reflectionA few months ago I did a deep dive into Efficient Lightweight JMS with Spring and ActiveMQ where I focused on the details for asynchronous sending and receiving of messages. In an ideal world all messaging would be asynchronous. If you need a response then you should set up an asynchronous listener and either have enough state stored in the service or in the message that you can continue processing once the response has been received. However, when ideals lead to complexity, we have to make the decision of how much complexity can we tolerate for the performance we need. Sometimes it just makes more sense to use a synchronous request/response.

Request Response with JMS

ActiveMQ documentation actually has a pretty good overview of how request-response semantics work in JMS.

You might think at first that to implement request-response type operations in JMS that you should create a new consumer with a selector per request; or maybe create a new temporary queue per request.

Creating temporary destinations, consumers, producers and connections are all synchronous request-response operations with the broker and so should be avoided for processing each request as it results in lots of chat with the JMS broker.

The best way to implement request-response over JMS is to create a temporary queue and consumer per client on startup, set JMSReplyTo property on each message to the temporary queue and then use a correlationID on each message to correlate request messages to response messages. This avoids the overhead of creating and closing a consumer for each request (which is expensive). It also means you can share the same producer & consumer across many threads if you want (or pool them maybe).

This is a pretty good start but it requires some tweaking to work best in Spring. It also should be noted that Lingo and Camel are also suggested as options when using ActiveMQ. In my previous post I addressed why I don’t use either of these options. In short Camel is more power than is needed for basic messaging and Lingo is built on Jencks, neither of which have been updated in years.

Request Response in Spring

The first thing to notice is that its infeasible to create a consumer and temporary queue per client in Spring since pooling resources is required overcome the JmsTemplate gotchas. To get around this, I suggest using predefined request and response queues, removing the overhead of creating a temporary queue for each request/response. To allow for multiple consumers and producers on the same queue the JMSCorrelationId is used to correlated the request with its response message.

At this point I implemented the following naive solution:

@Component
public class Requestor {

    private static final class CorrelationIdPostProcessor implements MessagePostProcessor {

        private final String correlationId;

        public CorrelationIdPostProcessor( final String correlationId ) {
            this.correlationId = correlationId;
        }

        @Override
        public Message postProcessMessage( final Message msg ) throws JMSException {
            msg.setJMSCorrelationID( correlationId );
            return msg;
        }
    }

    private final JmsTemplate jmsTemplate;

    @Autowired
    public RequestGateway( JmsTemplate jmsTemplate ) {
        this.jmsTemplate = jmsTemplate;
    }

    public String request( final String request, String queue ) throws IOException {
        final String correlationId = UUID.randomUUID().toString();
        jmsTemplate.convertAndSend( queue+".request", request, new CorrelationIdPostProcessor( correlationId ) );
        return (String) jmsTemplate.receiveSelectedAndConvert( queue+".response", "JMSCorrelationID='" + correlationId + "'" );
    }
}

This worked for a while until the system started occasionally timing out when making a request against a particularly fast responding service. After some debugging it became apparent that the service was responding so quickly that the receive() call was not fully initialized, causing it to miss the message. Once it finished initializing, it would wait until the timeout and fail. Unfortunately, there is very little in the way of documentation for this and the best suggestion I could find still seemed to leave open the possibility for the race condition by creating the consumer after sending the message. Luckily, according to the JMS spec, a consumer becomes active as soon as it is created and, assuming the connection has been started, it will start consuming messages. This allows for the reordering of the method calls leading to the slightly more verbose but also more correct solution. (NOTE: Thanks to Aaron Korver for pointing out that ProducerConsumer needs to implement SessionCallback and that true needs to be passed to the JmsTemplate.execute() for the connection to be started.)

@Component
public class Requestor {

    private static final class ProducerConsumer implements SessionCallback<Message> {

        private static final int TIMEOUT = 5000;

        private final String msg;

        private final DestinationResolver destinationResolver;

        private final String queue;

        public ProducerConsumer( final String msg, String queue, final DestinationResolver destinationResolver ) {
            this.msg = msg;
            this.queue = queue;
            this.destinationResolver = destinationResolver;
        }

        public Message doInJms( final Session session ) throws JMSException {
            MessageConsumer consumer = null;
            MessageProducer producer = null;
            try {
                final String correlationId = UUID.randomUUID().toString();
                final Destination requestQueue =
                        destinationResolver.resolveDestinationName( session, queue+".request", false );
                final Destination replyQueue =
                        destinationResolver.resolveDestinationName( session, queue+".response", false );
                // Create the consumer first!
                consumer = session.createConsumer( replyQueue, "JMSCorrelationID = '" + correlationId + "'" );
                final TextMessage textMessage = session.createTextMessage( msg );
                textMessage.setJMSCorrelationID( correlationId );
                textMessage.setJMSReplyTo( replyQueue );
                // Send the request second!
                producer = session.createProducer( requestQueue );
                producer.send( requestQueue, textMessage );
                // Block on receiving the response with a timeout
                return consumer.receive( TIMEOUT );
            }
            finally {
                // Don't forget to close your resources
                JmsUtils.closeMessageConsumer( consumer );
                JmsUtils.closeMessageProducer( producer );
            }
        }
    }

    private final JmsTemplate jmsTemplate;

    @Autowired
    public Requestor( final JmsTemplate jmsTemplate ) {
        this.jmsTemplate = jmsTemplate;
     }

    public String request( final String request, String queue ) {
        // Must pass true as the second param to start the connection
        return (String) jmsTemplate.execute( new ProducerConsumer( msg, queue, jmsTemplate.getDestinationResolver() ), true );
    }
}

About Pooling

Once the request/response logic was correct it was time to load test. Almost instantly, memory usage exploded and the garbage collector started thrashing. Inspecting ActiveMQ with the Web Console showed that MessageConsumers were hanging around even though they were being explicitly closed using Spring’s own JmsUtils. Turns out, the CachingConnectionFactory‘s JavaDoc held the key to what was going on: “Note also that MessageConsumers obtained from a cached Session won’t get closed until the Session will eventually be removed from the pool.” However, if the MessageConsumers could be reused this wouldn’t be an issue. Unfortunately, CachingConnectionFactory caches MessageConsumers based on a hash key which contains the selector among other values. Obviously each request/response call, with its necessarily unique selector, was creating a new consumer that could never be reused. Luckily ActiveMQ provides a PooledConnectionFactory which does not cache MessageConsumers and switching to it fixed the problem instantly. However, this means that each request/response requires a new MessageConsumer to be created. This is adds overhead but its the price that must be payed to do synchronous request/response.

Follow

Get every new post delivered to your Inbox.