My new job uses JMS, finally giving me a good reason to really play with this technology. After reviewing the coding techniques, I needed a JMS Provider to work against that would be quick and easy to set up – Apache ActiveMQ. It was quick and easy:
- Went to http://activemq.apache.org/activemq-530-release.html and downloaded the Unix version for my Mac.
- Unzipped and made sure executable.
- Made sure the activemq file under bin/macosx was executable
- From the install directory, executed: bin/macosx/activemq start
- Went to the admin UI to set up topics and queues: http://localhost:8161/admin/
- Stopped the server with: bin/macosx/activemq stop
How easy was that?! Now, on to the JMS coding, where I ran into a few speed bumps along the way.
First, if you are going to do JMS development outside of a J2EE container, you need to include jms.jar (which you can download standalone from Sun).
Second, this exception pops up while trying to get my JNDI contex:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Googling on this, Sun’s forum states that when this happens, most likely it is due to installing the JDK before uninstalling the previous JDK. On a Windows this is not as big of a deal, but uninstalling and then installing the JDK is a little more challenging on the Mac. Fortunately, a little more research found another workaround:
Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.apache.activemq.jndi.ActiveMQInitialContextFactory"); props.setProperty(Context.PROVIDER_URL,"tcp://localhost:61616"); jndiContext = new InitialContext(props);
Third, it can’t find a number of the classes it needs. I included the following three jar files from the ActiveMQ installation:
Fourth, what name should I use for the connection factory for jndiContext.lookup? “ConnectionFactory” ends up working well.
Fifth, its time to set up the topics and queues. I turned to the Admin UI, able to set up the physical queues and topics but seeing no way to set up the JNDI logical queues and topics. Trying to create destinations without these is not working. However, it turns out that ActiveMQ makes it really easy to set up with dynamicQueues and dynamicTopics:
queueDestination = (Destination) jndiContext.lookup("dynamicQueues/SyncQueue"); topicDestination = (Destination) jndiContext.lookup("dynamicTopics/SyncTopic");
After these issues, all the other work I did with JMS went pretty straight-forward.