Using Smalltalk as a Java Resume Filter
Last weekend I picked up My Job Went To India (And All I Got Was This Lousy Book) by Chad Fowler. I must admit that I found the title and the cover to be a bit cheesy, but I decided to look through it anyway. (Insert cliché here about judging a book by its cover.) While reading it in the bookstore, I found it to be such a good read that I decided to bring it home. (In general, if I can’t put down a book at the bookstore, that is the deciding factor on whether I decide to purchase it.) It is full of…well…pragmatic advice on how to improve and enjoy yourself and your career in software development. As I was reading through it, I thought to myself “this really belongs in The Pragmatic Programmers” series. It was only after bringing it home that I realized that not only did it already belong (again, the cover does not look like the other books in the series), but that the author is a coauthor of Programming Ruby, which is another book that I’m going through at the moment.
One of the most interesting anecdotes that Chad gives is when he is going through hundreds of resumes looking for Java developers. After having spent many hours going through candidates that were unqualified, he suggests adding Smalltalk as one of the required keywords for the resume search. Even though Smalltalk won’t be used in the project, using this technique he is able to narrow the resumes down considerably. The developers that make this cut turn out to be “diamonds in the rough.” These are the guys that really enjoy to program, and people that enjoy to program are usually pretty good at it.
Languages are not just a set of instructions to a computer, they are also a medium to express thought on problem solving. It is not hard for a seasoned developer to pick up a new language, but it does take a little more time to think in that language. For a simple example (and a bit of a digression), take a for loop in Java:
for (int i = 0; i < 5; i++) {
System.out.println("Hello");
}
Here’s how to express this loop in Ruby (thanks, Why the Lucky Stiff!):
5.times { print "Hello" }
In the Java loop, we are incrementing an integer variable and printing to the console during each iteration. In the Ruby loop, the number 5 is an actual object, and it contains a method called “times” that will execute the block of code that is passed to it the number of times represented by the integer object. This is reminicent of the Template design pattern that I’m used to using with JdbcTemplate in Spring, except that this is built into the Ruby language and this is a much more concise way of expressing it.
Back on topic, Chad makes the argument that knowing multiple languages makes you more attractive to perspective employers. Via his anecdote, he also demonstrates that this is a very effective way to filter out resumes when looking for good developers. Other than the career implications, being able to think of and express solutions in multiple languages enhances your creativity and effectiveness for solving everyday problems.
WBC 2006 in Orlando
This posting is a little late, but these are pictures from when I, along with my wife Maria and friend Omar, went to the World Baseball Classic in Orlando about 7 weeks ago. We saw (and cheered on) the Dominican Republic play against Italy. This was a game that featured quite a bit of offense, especially from the Dominican team. Although I (and just about everyone else in the stands) enjoyed the home run display by the likes of Albert Pujols and Adrian Beltre, I was somewhat apprehensive about this team depending so much on the long ball. As I was afraid would happen, it led to their demise vs. Cuba in the semi finals. Nevertheless, I really enjoyed watching these games, especially seeing the styles of play by the various countries. I was really impressed by the strict discipline of the Asian teams, especially at the plate. Latin American players in general (and Dominicans in particular) tend to be a little impatient at the plate and swing at pitches that should not be swung at.
Small tangent: I’m thrilled that my hometown Mets are first in their division thus far, but I’d like to see Jose Reyes get on base some more. As of today he has an on base percentage of .296 for the season and .303 lifetime. Those are not good numbers for a leadoff man, especially for someone with as much speed as him. I’d love to see more plate discipline from the likes of him.
Anyway, here are some pictures at the game:

Jose Reyes leads off

Big Papi takes a cut

The crowd representing…

The enthusiastic victory celebration

Me and Omar enjoying the victory
Using Lingo with Spring 2.0 Message Driven POJOs
Following the example on the Lingo website, I set up a simple service and exposed it through JMS. Using Lingo, you can make RPC style (as well as asynchronous) calls to services using JMS as the transport. For my sample application, I used Tibco JMS (E4JMS) as the provider.
For the server side, I did this:
<beans>
<!-- the server side -->
<bean id="server" class="org.logicblaze.lingo.jms.JmsServiceExporter">
<property name="service" ref="serverImpl"/>
<property name="serviceInterface" value="ets.lingotest.Reverse"/>
<property name="connectionFactory" ref="jmsFactory"/>
<property name="destination" ref="requestDestination"/>
</bean><bean id="serverImpl" class="ets.lingotest.ReverseServerImpl" singleton="true"/>
<!-- JMS ConnectionFactory to use -->
<bean id="jmsFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>GenericConnectionFactory</value>
</property>
</bean><bean id="requestDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>queue.sample</value>
</property>
</bean>
</beans>
And the client looks like this:
<beans>
<!-- client side proxy-->
<bean id="client" class="org.logicblaze.lingo.jms.JmsProxyFactoryBean">
<property name="serviceInterface" value="ets.lingotest.Reverse"/>
<property name="connectionFactory" ref="jmsFactory"/>
<property name="destination" ref="requestDestination"/>
</bean><!-- JMS ConnectionFactory to use -->
<bean id="jmsFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>GenericConnectionFactory</value>
</property>
</bean><bean id="requestDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>queue.sample</value>
</property>
</bean>
</beans>
And here is the interface being exposed:
public interface Reverse {
public String reverse(String s);
}
With this setup, a single MessageListener is set up to listen on the queue. Easy setup, but not very scalable. To do a proper setup, you can use Jencks to pool JMS resources and process the messages asynchronously.
Another option with Spring 2.0 is to use the new asynchronous JMS processing classes. These classes create and manage threads that hold connections to the JMS queue. For my example, I will use DefaultMessageListenerContainer.
I make this change to the server application context:
<beans>
<!-- the server side -->
<bean id="server" class="org.logicblaze.lingo.jms.JmsServiceExporter">
<property name="service" ref="serverImpl"/>
<property name="serviceInterface" value="ets.lingotest.Reverse"/>
<property name="connectionFactory" ref="jmsFactory"/>
<!--<property name="destination" ref="requestDestination"/>-->
</bean><bean id="serverImpl" class="ets.lingotest.ReverseServerImpl" singleton="true"/>
<!-- JMS ConnectionFactory to use -->
<bean id="jmsFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>GenericConnectionFactory</value>
</property>
</bean><bean id="requestDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>queue.sample</value>
</property>
</bean><!--Spring async message processing -->
<bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsFactory"/>
<property name="destination" ref="requestDestination"/>
<property name="messageListener" ref="server"/>
<property name="concurrentConsumers" value="5"/>
</bean></beans>
The JmsServiceExporter no longer has the destination property configured; instead it is set as the messageListener property of DefaultMessageListenerContainer. Note the DefaultMessageListenerContainer knows all about the JMS connection and queue where the messages will be coming in. It also has the concurrentConsumers value set to 5, so there will be 5 threads listening for messages.
Previously, the server output was:
ReverseServerImpl [E4JMS Session Dispatcher (171)] INFO - Server got string: hello world
ReverseServerImpl [E4JMS Session Dispatcher (171)] INFO - Server returning: dlrow olleh
Now it is
ReverseServerImpl [DefaultMessageListenerContainer0] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer0] INFO - Server returning: dlrow olleh
Note that it is now DefaultMessageListenerContainer0 handling the message instead of E4JMS Session Dispatcher. I also noticed that the message processing is set up round robin, so executing the client multiple times yields:
ReverseServerImpl [DefaultMessageListenerContainer0] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer0] INFO - Server returning: dlrow olleh
ReverseServerImpl [DefaultMessageListenerContainer1] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer1] INFO - Server returning: dlrow olleh
ReverseServerImpl [DefaultMessageListenerContainer2] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer2] INFO - Server returning: dlrow olleh
ReverseServerImpl [DefaultMessageListenerContainer3] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer3] INFO - Server returning: dlrow olleh
ReverseServerImpl [DefaultMessageListenerContainer4] INFO - Server got string: hello world
ReverseServerImpl [DefaultMessageListenerContainer4] INFO - Server returning: dlrow olleh
This setup is pretty simple, but I’m not sure what the implications are as far as performance and scalability, especially given the usage patterns of JmsTemplate as documented by James Strachan. I’m curious to hear from anyone that has a similar setup or from anyone that has suggestions/feedback.
NY Transit Strike
It looks like the pending transit strike in New York is causing all sorts of anxiety among New Yorkers. Today the New York Times reported that no deal had been struck at the end of the current contract; as a result the TWU plans to call a strike with two private bus companies in Queens, Triboro and Jamaica Buses, Inc.. The reason is because these routes have not been taken over by the city yet, thus the Taylor Law does not apply to them. One side effect of this that nobody in the media has mentioned yet (and the first thing that came to mind) is that these buses serve many areas that are not exactly affluent. It is somewhat ironic that this strike would affect primarily working and lower class citizens. Queens residents in the middle class and higher are much more likely to own a car, unlike their Manhattan counterparts.
Closing thoughts on TSE 2005
A little late, but here are my closing thoughts on The Spring Experience 2005. The last session that I attended was my own, the Symantec case study. This session focused on our call center case tracking application and how it has evolved over time while making use of Spring. As Jim Moore mentioned, the project that was discussed during the Accenture case study had many similarities to ours, including:
- infrastructure, such as JBoss, Tomcat, Oracle 9i
- multiple Spring configuration files, swapped out for testing and production
- extensive unit testing of all layers outside of the container
- migration from hard coded dependencies to dependency injection, which makes all of this testing possible
In our case study we cover the evolution of our application from client/server to multi-tier, the issues that we ran into when creating a middle tier, and how Spring helped us along the way. A reoccurring theme throughout the conference was how non invasive Spring is and how easy it is to use bits and pieces at a time instead of having to migrate to DI, AOP, DAO, security and everything else Spring has to offer all at once. This was the case with our middle tier, where we adopted pieces of Spring as time went on. Before we knew it, we had a very flexible and stable solution that was portable to any J2EE container.
We had a small crowd, but had some good questions and dialog about our experiences. I look forward to the JavaLobby guys putting session audio (and hopefully video) on their site in the coming weeks. For those interested, we have posted our slides.
I must say that TSE was one of the best conferences that I have attended, if not the best. When filling out my survey, one of the questions asked which speaker(s) were the best. My honest answer was all of them, because I was able to learn something at each of the talks that I attended. The speakers and attendees alike were very intelligent and articulate; clearly these folks are the leaders of our industry. The accommodations and location were excellent, and to repeat what has already been said by others, Jay Zimmerman and Keith Donald pulled this conference off to perfection. I look forward to returning next year.