JMS let’s you send messages containing for example a String, array of bytes or a serializable Java object, from one program to another. It doesn’t however use a direct connection from program A to program B, instead the message is sent to a JMS provider and put there in a Queue where it waits until the other program receives it.
MessageProducer is a Java program sending a JMS message to a Queue on the JMS Provider. MessageConsumer is another program which receives that message. These two programs can run on separate machines and all they have to know to communicate is the URL of the JMS Provider. The Provider can be for example a Java EE server, like JBoss or Glassfish. But don’t be afraid, you don’t need a full-blown JEE server to send a JMS message. In this article we will use ActiveMQ which is lightweight and easy to use.
First we need to download ActiveMQ. If you are using Linux, you can get it from this link. For Windows you can use this link. In case the links don’t work, you can find the files in ‘Downloads’ section on ActiveMQ’s webpage.
After the download, extract it to any directory and run the ‘activemq’ program from beneath the ‘{path-where-you-extracted-activemq}/bin’ directory:
user@user-laptop:~/activemq/apache-activemq-5.3.0/bin$ ./activemq |
You should see a bunch of INFO messages appearing on the terminal:
... INFO | ActiveMQ Web Demos at http://0.0.0.0:8161/demo INFO | RESTful file access application at http://0.0.0.0:8161/fileserver INFO | Started SelectChannelConnector@0.0.0.0:8161 |
Now the ActiveMQ server is up and running. You can close it any time by pressing Ctrl-C. ActiveMQ has a nice admin console, where you can see a lot of useful informations and change the settings: http://localhost:8161/admin/.
Now that we have a JMS provider running, let’s write our message producer and consumer programs. For that, you will need to put the ActiveMQ’s JAR file on the class path. The file you need is called (for version 5.3.0) ‘activemq-all-5.3.0.jar’ or something similar and is in the extracted ActiveMQ directory. In Eclipse you could click right mouse button on your project and choose Properties->Java Build Path->Libraries->Add External Library.
Here is the code of the program sending (producing) the messages:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: |
import javax.jms.*;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Producer {
// URL of the JMS server. DEFAULT_BROKER_URL will just mean
// that JMS server is on localhost
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
// Name of the queue we will be sending messages to
private static String subject = "TESTQUEUE";
public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server and starting it
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
// JMS messages are sent and received using a Session. We will
// create here a non-transactional session object. If you want
// to use transactions you should set the first parameter to 'true'
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
// Destination represents here our queue 'TESTQUEUE' on the
// JMS server. You don't have to do anything special on the
// server to create it, it will be created automatically.
Destination destination = session.createQueue(subject);
// MessageProducer is used for sending messages (as opposed
// to MessageConsumer which is used for receiving them)
MessageProducer producer = session.createProducer(destination);
// We will send a small text message saying 'Hello' in Japanese
TextMessage message = session.createTextMessage("こんにちは");
// Here we are sending the message!
producer.send(message);
System.out.println("Sent message '" + message.getText() + "'");
connection.close();
}
}
|
There is a lot going on here. The Connection represents our connection with the JMS Provider – ActiveMQ. Be sure not to confuse it with SQL’s Connection. ‘Destination’ represents the Queue on the JMS Provider that we will be sending messages to. In our case, we will send it to Queue called ‘TESTQUEUE’ (it will be automatically created if it didn’t exist yet).
What you should note is that there is no mention of who will finally read the message. Actually, the Producer does not know where or who the consumer is! We are just sending messages into queue ‘TESTQUEUE’ and what happens from there to the sent messages is not of Producer’s interest any more.
The most interesting for us part in the above code is probably line 46 where we use function ‘.createTextMessage(”こんにちは”);’ to send a text message (in this case to our Japanese friend).
Now let’s see how to receive (consume) the sent message. Here is the code for the Consumer class:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: |
import javax.jms.*;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Consumer {
// URL of the JMS server
private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
// Name of the queue we will receive messages from
private static String subject = "TESTQUEUE";
public static void main(String[] args) throws JMSException {
// Getting JMS connection from the server
ConnectionFactory connectionFactory
= new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
// Creating session for seding messages
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
// Getting the queue 'TESTQUEUE'
Destination destination = session.createQueue(subject);
// MessageConsumer is used for receiving (consuming) messages
MessageConsumer consumer = session.createConsumer(destination);
// Here we receive the message.
// By default this call is blocking, which means it will wait
// for a message to arrive on the queue.
Message message = consumer.receive();
// There are many types of Message and TextMessage
// is just one of them. Producer sent us a TextMessage
// so we must cast to it to get access to its .getText()
// method.
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message '"
+ textMessage.getText() + "'");
}
connection.close();
}
}
|
As you see, it looks pretty similar to the Producer’s code before. Actually only the part starting from line 35 is substantially different. We produce there a MessageConsumer instead of MessageReceiver and then use it’s .receive() method instead of .send(). You can see also an ugly cast from Message to TextMessage but there is nothing we could do about it, because .receive() method just returns interface Message (TextMessage interface extends Message) and there are no separate methods for receiving just TextMessage’s.
Compile now both programs remembering about adding ActiveMQ’s JAR file to the classpath. Before running them be also sure that the ActiveMQ’s instance is running (for example in a separate terminal). First run the Producer program:
2009/11/14 15:56:37 org.apache.activemq. transport.failover.FailoverTransport doReconnect 情報: Successfully connected to tcp://localhost:61616 Sent message 'こんにちは' |
If you see something similar to the output above (especially the ‘Sent message’ part) then it means that the message was successfully sent and is now inside the TESTQUEUE queue. You can enter the Queues section in the ActiveMQ’s admin console http://localhost:8161/admin/queues.jsp and see that there is one message sitting in TESTQUEUE:

In order to receive that message run now the Consumer program:
2009/11/14 15:58:03 org.apache.activemq. transport.failover.FailoverTransport doReconnect 情報: Successfully connected to tcp://localhost:61616 Received message 'こんにちは' |
If you are getting above input (or something similar) everything went ok. The message was successfully received.
You are now probably thinking “Why would anybody want to do that??”. In fact, the code presented here to transfer just a small text message was pretty big, and you also needed an instance of ActiveMQ running, and dependencies in the classpath and all that…. Instead of using JMS we could use plain TCP/IP with few times less effort. So, what are good points of using JMS compared to simple TCP/IP or Java RMI? Here they are:
- Communication using JMS is asynchronous. The producer just sends a message and goes on with his business. If you called a method using RMI you would have to wait until it returns, and there can be cases you just don’t want to lose all that time.
- Take a look at how we run the example above. At the moment we run the Producer to send a message, there was yet no instance of Consumer running. The message was delivered at the moment the Consumer asked ActiveMQ for it. Now compare it to RMI. If we tried to send any request through RMI to a service that is not running yet, we would get a RemoteException. Using JMS let’s you send requests to services that may be currently unavailable. The message will be delivered as soon as the service starts.
- JMS is a way of abstracting the process of sending messages. As you see in the examples above, we are using some custom Queue with name ‘TESTQUEUE’. The producer just knows it has to send to that queue and the consumer takes it from there. Thanks to that we can decouple the producer from the consumer. When a message gets into the queue, we can do a full bunch of stuff with it, like sending it to other queues, copying it, saving in a database, routing based on its contents and much more. here you can see some of the possibilities.
JMS is widely used as a System Integration solution in big, distributed systems like those of for example banks. There are many books dealing with this huge topic, for example Enterprise Integration Patterns. If you want to learn more about JMS itself you can do it for example on this JMS Tutorial on Sun’s webpage.
50 Comments until now
Nice write up!
If your familiar with RMI and JMS, you might want to take a peek at the RMI via JMS project: http://rmiviajms.fusesource.org/
It combines the best of both worlds.
Regards,
Hiram
[...] This post was mentioned on Twitter by brucesnyder, bubbl. bubbl said: JavaBlogging » Simple guide to Java Message Service (JMS) using ActiveMQ http://ff.im/-c27hV [...]
[...] 4) 23 Nov 09 – Mironsadziak published a simple guide to Java Message Service (JMS) using ActiveMQ [...]
[...] cateva despre jms – de la sun – de la alt blogger (recomandat) – de la un indian – de la [...]
I like reading posts like that: easy to understand and nice working example. Do we need more to start with JMS? Good job.
Can we produce 2 queue for same topic
This is excellent one with good explanation.
Good article on JMS… easy to understand…
Thank you for this post : i was trying to do the same on my own but was facing a problem with the url to provide.
Thx to you it now works !
nice work for mq with java
Good one JMS with MQ
Thanks!!!!
Hi, I am trying to learn a little about asynchronous messaging. I like your post alot but I do not know how to run the “producer” and “consumer” programs. I have activemq and the web admin interface running and I have put the activemq jar file in the classpath. How do I run the consumer and producer programs please? Thanks!
Ok hi Gil again here. I figured out how to compile and run the examples by looking at some other websites. Here is what I did:
I put consumer.java and producer.java in /opt/activemq/examples/src directory. I tried to run them using
/opt/activemq/examples/ant producer
but I got an error about missing tools.jar in some directory so I searched on my machine and found a tools.jar that was somewhere else and copied it to the required location:
mkdir -p /usr/lib/jvm/java-6-openjdk/lib
cp -p /usr/lib/jvm/java-6-sun-1.6.0.20/lib/tools.jar /usr/lib/jvm/java-6-openjdk/lib/.
Then I cd /opt/activemq/example directory
When I ran
ant consumer
again, now it complained that my file was named consumer.java but it is supposed to be Consumer.java so I renamed with capital letter (a java thing I guess .java files must start with capital letter?- I am utterly java illiterate) and then I know I must also do same thing with producer.java so I make that Producer.java and then I run again:
/opt/activemq/example/ant producer
and it ran perfect! I find 2000 messages in my TEST.FOO queue by looking at web admin console.
Then I ran
/opt/activemq/example/ant consumer
and the 2000 message are dequeued.
Thank you! this is what I was looking for I am trying to learn about asynchronous messaging. I am an Oracle DBA 15 years but just now learning about messaging gateways. This will help me alot!
Well my previous post was nonsense of course. When I ran /opt/activemq/examples ant producer I was only running “build.xml” and this had nothing to do with your programs.
I still don’t know how to compile and use your program.
Hi Gil,
Thank you for your post.
To compile my programs, first have them in Producer.java and Consumer.java files. Then run:
javac Producer.java
javac Consumer.java
from the directory where they are. (Be sure you have activemq jar file in your classpath). Since they are in default package (no ‘package’ declaration in them), they don’t have to be in any subdirectory.
After compiling, you will get files Producer.class and Consumer.class in your directory. Now you can run them with:
java Producer
java Consumer
You don’t have to use ant for this entire process.
A really well written blog ! Example runs perfectly in one shot.
Thank you
Hi Miron,
The post is simply good and neatly demonstrates the working with queue.
I am more interested to configure the same within Tomcat 6. Can you please provide a step by step methodology to like setting ActiveMQ within Tomcat with a sample application.
This will be really useful for us.
Regards,
R.G. Karthic Balaji
Thanks this was the best and most clear example on activemq I found on google. Congrats
Simple, short and a good tutorial. Thanks you.
Got Class not found exception when i try to run Producer
javac producer.java
java Producer
Thanks for this Tutorial..Very simple to understand….
iphone unlock
unlock iphone
unlock iphone how to unlock iphone iphone unlock
My computer was acting real funny, hanging up in the middle of processes, not letting me access task manager to quit them, etc.. I started in Safe Mode with networking and completed a full virus scan. I ran Chkdsk and it took 18 hours. It replaced bad clusters in about 20 files. Now Windows won’t start. It gives me the option to repair and I click on it, but nothing ever happens other than a black screen with my cursor arrow on it. I tried to start Windows normally and the same thing happens. Please only answer if you know what you’re talking about. Teens trying to up their points count by giving stupid answers will get thumbs down. how to unlock iphone
unlock iphone unlock iphone [url=http://ounlockiphone.com]iphone unlock [/url] iphone unlock
Super City Shot risparmia acquistando ristoranti, trattamenti benessere, abbonamenti, e tanto altro ad un prezzo imbattibile. I nostri deal promuovono offerte di attività commerciali vicino a te
groupalia
Thanks A lot for this nice blog
Hi Miron,
Nice blog, I was try it and succeed, btw do you have any example how to use message listener to consume queue?
sorry my english is bad.
Nurse And Drug Addiction http://miamibeatz.com/ – tadalafil 20mg Solo quando il soggetto viene eccitato, il Cialis diventa un facilitatore della€™erezione e del suo mantenimento per un tempo prolungato. [url=http://miamibeatz.com/]cheap cialis no prescription[/url]
Excellent article. I have to test message queueing and was looking for some easy to understand article. It is exactly what I was looking for. Thanks for it.
Thanks i love your article about JavaBlogging » Simple guide to Java Message Service (JMS) using ActiveMQ
Just started reading stuff on ActiveMQ and java implementation. Found this very helpful.
i am working on this ActiveMQ JMS SERVER…ur example helped alot…thanks for that..but now i have a trouble ..ie…
i have to built PUBLISH and SUBSCRIBE using the ACTIVEMQ JMS server……thanks in advance..i am in hurry
Hello, just required you to know I he added your website to my Google bookmarks due to your layout. But seriously, I think your net website has 1 in the freshest theme I??ve came across. It extremely helps make studying your weblog significantly easier.
so good
Good One, works well,
However I had to resolve a error “Failed to load class org.slf4j.impl.StaticLoggerBinder”.
I could resolve that by adding compatible
slf4j-simple jars of slf4j-1.4.3 available at http://www.slf4j.org/dist/
Hi ,
In simple terms you have explained JMS .
Great job buddy .
Thanks for your post.
Regards,
Keshav
I’m only 15, but i’m wanting to raise money to be a expensive trip pick up. We are intending on getting a summer job, nevertheless it usually only pays minimum wage. I just want other people’s opinions on be it safe and a good option becoming a blogger to acquire money. thanks!.
Thanks for the easy explanation.
Very good matter. I have discovered a whole lot interesting things right here. Carry on.
I am new of using activemq, and don’t have any idea what is this all about. but because of your explanation, i totally understand now what is activemq is all about. Thanks for the wonderful Explanation and sample.
Very informative to the point article
Thanks Miron
Wonderful post. You Explained the concept in a concise manner and the sample code works with no problems. I would recommend this post to anyone who would like to start learning JMS.
Very Nice.
I had a lot of problems with java error due to SLF4J.
To be more specific I had this error:
Exception in thread “main” java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
The solution was to add an older version of the jar file from SLF4J.
” You will also need SLF4J (Simple Logging Facade for Java): slf4j-simple-1.5.11.jar
NOTE: version 1.6+ will not work with the current version of ActiveMQ (5.5.0)
You will need to download version 1.5.11 here: http://grepcode.com/snapshot/repo1.maven.org/maven2/org.slf4j/slf4j-simple/1.5.11 ”
from http://myadventuresincoding.wordpress.com/category/activemq/
I’m just putting it for future reference, and for some poor guy (like me) trying to find it on Google
GREAT POST btw
helped me a lot
thanks
Very good article……..
Thanks…it was a nice and easy article.
Great work. Kudos to the author for posting such a simple yet lovely article… Would like to see more such articles….
This was good example and it worked perfectly well.
I need to use the same basics to come up with a secure publish-subscribe system on the topic published. such the subscribers can subscribe to the topic. what do i need to use. ?
This blog was really helpfull for me as a beginners found this as a stepping stone and completed my activeMq work
thanks brother
Very nice post, I surely love this site, keep it up.
Hey,can’t I invoke the producer.java from a java.lang.NoClassDefFoundError: javax/jms/ConnectionFactory as exceptions.
can someone please pint me in the right direction.
Hey,can’t I invoke the Producer.java from a jsp file by creating an instance of Producer.java
I keep getting java.lang.NoClassDefFoundError: javax/jms/ConnectionFactory as exceptions.
can someone please pint me in the right direction.
Add your Comment!