l i n u x - u s e r s - g r o u p - o f - d a v i s
Next Meeting:
July 7: Social gathering
Next Installfest:
Latest News:
Jun. 14: June LUGOD meeting cancelled
Page last updated:
2010 Oct 20 20:11

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
[vox-tech] Chat program in 100 lines of code!
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vox-tech] Chat program in 100 lines of code!

I read a PERL column  that Randal Schwartz wrote a few years back
(maybe 10 years back) about using a gpg signed email and the body with an
image or some content that could be used to update a website. You would
send the message and a procmail recipe would intercept the message and
pipe it through a PERL script.

So, what if we could just write programs like this? Ones that could send
messages back and forth? Well, I recently discovered Java Message Service
(JMS) and it looks very cool. I was looking through the O'Reilly Java
Message service book and I was able to write a chat program with just
a few lines of code and the ActiveMQ message broker.

The following code is from Chapter 2 of the "Java Message Service, 2nd
Ed" by Mark Richards et al, 2009, ISBN-13 978-0-596-52204-9. Some of the
description in the book didn't make sense, so here is my implementation.

First, make sure you have Java installed. I use OpenJDK.

Download ActiveMQ

Remember the directory when you unpacked the activeMQ.
$ export ACTIVEMQ_HOME=<wherever you put it>

Add the following to your classpath. The following also adds the current
working directory to your CLASSPATH, so if you don't have it, you will
probably need it to run the java Chat program below.

$ export CLASSPATH=ACTIVEMQ_HOME/activemq-all-5.4.1.jar:.:$CLASSPATH

Edit the config file and add the following configuration to the
conf/activemq.xml configuration file right after the </destinationPolicy>
end directive.

$ cat conf/activemq.xml

	<topic name="topic1" physicalName="jms.topic1" />

Start your ActiveMQ messaging broker. I assume it is a broker. I believe
it will create a default security policy, so you might have to follow
a few directiions.

$ bin/activemq start

Change to some other directory such as a source folder.

$ cd ~/src

Create the file jndi.properties. Content is as follows:
$ cat jndi.properties

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = tcp://localhost:61616
connectionFactoryNames = TopicCF
topic.topic1 = jms.topic1

Make a ch02 subdirectory.
$ mkdir ch02

Content is the following for the java Chat program:
$ cat Chat.java

package ch02;

import java.io.*;
import javax.jms.*;
import javax.naming.*;

public class Chat implements javax.jms.MessageListener{
    private TopicSession pubSession;
    private TopicPublisher publisher;
    private TopicConnection connection;
    private String username;

    /* Constructor used to Initialize Chat */
    public Chat(String topicFactory, String topicName, String username) 
        throws Exception {
    	// Obtain a JNDI connection using the jndi.properties file
        InitialContext ctx = new InitialContext();

        // Look up a JMS connection factory
        TopicConnectionFactory conFactory = 

        // Create a JMS connection
        TopicConnection connection = conFactory.createTopicConnection();

        // Create two JMS session objects
        TopicSession pubSession = connection.createTopicSession(
        	false, Session.AUTO_ACKNOWLEDGE);        
        TopicSession subSession = connection.createTopicSession(
        	false, Session.AUTO_ACKNOWLEDGE);

        // Look up a JMS topic
        Topic chatTopic = (Topic)ctx.lookup(topicName);

        // Create a JMS publisher and subscriber
        TopicPublisher publisher = 
        TopicSubscriber subscriber = 
            subSession.createSubscriber(chatTopic, null, true);

        // Set a JMS message listener

        // Intialize the Chat application variables
        this.connection = connection;
        this.pubSession = pubSession;
        this.publisher = publisher;
        this.username = username;

        // Start the JMS connection; allows messages to be delivered
        connection.start( );

    /* Receive Messages From Topic Subscriber */
    public void onMessage(Message message) {
        try {
            TextMessage textMessage = (TextMessage) message;
            String text = textMessage.getText( );
        } catch (JMSException jmse){ jmse.printStackTrace( ); }

    /* Create and Send Message Using Publisher */
    protected void writeMessage(String text) throws JMSException {
        TextMessage message = pubSession.createTextMessage( );
        message.setText(username+": "+text);

    /* Close the JMS Connection */
    public void close( ) throws JMSException {
        connection.close( );

    /* Run the Chat Client */
    public static void main(String [] args){
            if (args.length!=3)
                System.out.println("Factory, Topic, or username missing");

            // args[0]=topicFactory; args[1]=topicName; args[2]=username
            Chat chat = new Chat(args[0],args[1],args[2]);

            // Read from command line
            BufferedReader commandLine = new 
              java.io.BufferedReader(new InputStreamReader(System.in));

            // Loop until the word "exit" is typed
                String s = commandLine.readLine( );
                if (s.equalsIgnoreCase("exit")){
                    chat.close( ); // close down connection
                    System.exit(0);// exit program
                } else 
        } catch (Exception e){ e.printStackTrace( ); }

Compile the program. Change to the directory above to do this as follows:

$ cd ..
$ javac ch02/Chat.java

Now, run your chat client. Make sure that your CLASSPATH is set as above.

$ java ch02.Chat TopicCF topic1 John 

Now, from another terminal, set the same CLASSPATH environment and run the
Chat program with another user such as Mary.

$ java ch02.Chat TopicCF topic1 Mary

When you type and press return, the message should go to all who are connected.
Is this cool or what?

Brian Lavender

"Program testing can be used to show the presence of bugs, but never to
show their absence!"

Professor Edsger Dijkstra
1972 Turing award recipient
Lug-nuts mailing list
Brian Lavender

"Program testing can be used to show the presence of bugs, but never to
show their absence!"

Professor Edsger Dijkstra
1972 Turing award recipient
vox-tech mailing list

LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Appahost Applications
For a significant contribution towards our projector, and a generous donation to allow us to continue meeting at the Davis Library.