Home » Communications » XMPP IM with Smack for Java applications – Infrastructure for Instant Messaging

About Ilias Tsagklis

Ilias Tsagklis
Ilias is a software developer turned online entrepreneur. He is co-founder and Executive Editor at Java Code Geeks.

XMPP IM with Smack for Java applications – Infrastructure for Instant Messaging

This tutorial is the third part of the “Setting up an infrastructure for Instant Messaging” article series. In my previous tutorials, I showed you how to setup the Openfire IM Server and how to configure the Spark client in order to connect to that server. In this tutorial, I will show you how to add XMPP messaging capabilities to your own application.

I will use the Smack library, an Open Source XMPP (Jabber) client library for instant messaging and presence. Smack is a pure Java library and can be embedded into your applications to create anything from a full XMPP client to simple XMPP integrations.

XMPP is a simple XML protocol. Under the hood, XML messages are transmitted from the server to the client and vice versa. However, you don’t have to deal with those low level details, unless you want to. Smack hides all these via a well designed API. You can take a first hint of how the API works by reading the article “Instant Messaging in Java Made Easy: The Smack API”. I believe that you are familiar with the concept of instant messaging in general, so we are ready to write some code.

First download the library from the Ignite Realtime site. Since Smack is written in Java, it is cross-platform. The current version is 3.1.0 and I downloaded the tar.gz version (direct download here). After you extract the bundle file, you will find the library JARs along with the corresponding Javadocs. The online Javadocs can be found here (bookmark it to your favorite browser).

Create a new Eclipse project, let’s say under the name “XMPPProject”, and add the “smack.jar” and “smackx.jar” files into your classpath.

The main class that your client will use is XMPPConnection. As the name implies, it represents an XMPP connection to a remote server. Creating a connection and performing a login is as simple as the following code snippet:

// Create a connection to the igniterealtime.org XMPP server.
XMPPConnection connection = new XMPPConnection("myxmppserver.com");
// Connect to the server
// Most servers require you to login before performing other tasks.
connection.login("myuser", "mypass");

Of course, a more sophisticated configuration of the connection attributes is possible and that can be achieved by using the ConnectionConfiguration class. There are multiple parameters that can be configured, with the most significant being the server host and port and various security (encryption) issues. You can also configure the internal Smack stack by using the SmackConfiguration class.

ConnectionConfiguration config = 
     new ConnectionConfiguration(serverHost, serverPort);
XMPPConnection connection = new XMPPConnection(config);
connection.login("myuser", "mypass");

From a valid XMPPConnection, you can retrieve a ChatManager object. This one keeps track of references to all current chats and allows you to create Chat instances, i.e. series of messages sent between two users. Chat object are able of sending messages to other chat participants. You can use plain strings or construct XMPP message packets, represented by the Message class. Message class provides direct access to all of the message attributes, such as the message type. For processing incoming messages, you have to implement the MessageListener interface and attach it to a chat.

ChatManager chatManager = connection.getChatManager();
Chat chat = chatManager.createChat("mybuddy", new MyMessageListener());

You can also set your online status, also known as presence, by using the Presence class.

Presence presence = new Presence(Presence.Type.available);
presence.setStatus("What's up everyone?");

A new buddy can be added to your list by using the Roster class. A user’s roster is a collection of users a person receives presence updates for. A user can be associated with groups, but in the following example the new roster entry won’t belong to a group.

Roster roster = connection.getRoster();
roster.createEntry(user, name, null);

The main class I created is named “XmppManager” and the source code is the following:

package com.javacodegeeks.xmpp;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;

public class XmppManager {
    private static final int packetReplyTimeout = 500; // millis
    private String server;
    private int port;
    private ConnectionConfiguration config;
    private XMPPConnection connection;

    private ChatManager chatManager;
    private MessageListener messageListener;
    public XmppManager(String server, int port) {
        this.server = server;
        this.port = port;
    public void init() throws XMPPException {
        System.out.println(String.format("Initializing connection to server %1$s port %2$d", server, port));

        config = new ConnectionConfiguration(server, port);
        connection = new XMPPConnection(config);
        System.out.println("Connected: " + connection.isConnected());
        chatManager = connection.getChatManager();
        messageListener = new MyMessageListener();
    public void performLogin(String username, String password) throws XMPPException {
        if (connection!=null && connection.isConnected()) {
            connection.login(username, password);

    public void setStatus(boolean available, String status) {
        Presence.Type type = available? Type.available: Type.unavailable;
        Presence presence = new Presence(type);
    public void destroy() {
        if (connection!=null && connection.isConnected()) {
    public void sendMessage(String message, String buddyJID) throws XMPPException {
        System.out.println(String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
        Chat chat = chatManager.createChat(buddyJID, messageListener);
    public void createEntry(String user, String name) throws Exception {
        System.out.println(String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
        Roster roster = connection.getRoster();
        roster.createEntry(user, name, null);
    class MyMessageListener implements MessageListener {

        public void processMessage(Chat chat, Message message) {
            String from = message.getFrom();
            String body = message.getBody();
            System.out.println(String.format("Received message '%1$s' from %2$s", body, from));

Note that no security authentication is used and that the security mode is disabled. That means that there is no protection on the credentials exchange and that the messages are not secured. Smack API supports encryption, but I did not use it since I wanted to keep this tutorial simple.

Ok, let’s see how all the above can be combined in order to create a simple IM application. I will be using the Openfire server installed in a previous tutorial, along with the two users that were created.

First, I use my Spark client to login as user “testuser2”. Nothing special here. Next, I am creating a test class that uses “XmppManager”, connects to my Openfire server, logins as user “testuser1”, sets the online status to “available”, adds the “testuser2” to the roster and finally sends a message. Note that I created an infinite loop so that I can send messages from the Spark client and see them to my console. I am using the “isRunning” boolean to continue the looping. In a real application, this would be set to false if the program was to exit. Make sure you set the thread to sleep for some time, else your machine’s CPU will hit the roof. The test class is the following:

package com.javacodegeeks.xmpp;

public class XmppTest {
    public static void main(String[] args) throws Exception {
        String username = "testuser1";
        String password = "testuser1pass";
        XmppManager xmppManager = new XmppManager("myserver", 5222);
        xmppManager.performLogin(username, password);
        xmppManager.setStatus(true, "Hello everyone");
        String buddyJID = "testuser2";
        String buddyName = "testuser2";
        xmppManager.createEntry(buddyJID, buddyName);
        xmppManager.sendMessage("Hello mate", "testuser2@myserver");
        boolean isRunning = true;
        while (isRunning) {


Make sure you select the appropriate username/password and server settings.

If you run the program, you should see the incoming message to the Spark client. Answer to that message and then check your Eclipse console to ensure that the message was printed.

Note that “testuser2” received the message even though he hadn’t added “testuser1” as his buddy. This is the default behavior. Add the other user by hitting the “Add a Contact” button.

After the account is added, you will be able to see if the user is online and his current status as well.

Finally, you can retrieve the user’s roster and check the status of the existing contacts.

public void printRoster() throws Exception {
 Roster roster = connection.getRoster();
 Collection<RosterEntry> entries = roster.getEntries();  
 for (RosterEntry entry : entries) {
  System.out.println(String.format("Buddy:%1$s - Status:%2$s", 
      entry.getName(), entry.getStatus()));

That’s all! As always, the Eclipse project created can be found here.

Happy coding!!!

Related Articles :
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
Email address:

Leave a Reply

49 Comments on "XMPP IM with Smack for Java applications – Infrastructure for Instant Messaging"

newest oldest most voted
Notify of

Hi Ilias,
Is it possible with the Smack API to get all users presence status & writing a common listener to all users so that what ever the users typed my method should be notified.

vimal mishra

I want to print all the details of the openfire server on server GUI like server uptime , CPU usage , Active connection Bandwidth etc.I am new in java .I want some help if any one can help me out.I want a code for that.

Sachin Raghav

Hi Ilias Tsagklis,
Can you tell me please how we can make xmpp chat server for group chatting?


Hi llias,

I got an compilation error: in Line number 41.
It says there is no function called setSASLAuthenticationEnabled(false);


can i use tomat server instead of the one you specified .

Majid Arif

it was very helpful and also it works very very well thanks buddy may live long salute u!


xception in thread “main” service-unavailable(503)
at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:78)


I am getting this issue please help me:
Could not connect to Android8:5222.: remote-server-timeout(504) Could not connect to Android8:5222.
caused by: java.net.UnknownHostException: Host is unresolved: Android8
at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:893)


greeat tutorial ! but sir i want a common chat system which will support both android and window phone platform what will be the right option for me.please help


it’s very usefull :D
greetings from Colombia

Hello sir, very nice tutorial. I am developing a chat App.In one scenario i am sending message to a ROOM ID and the people who are present in that room are getting the message. Now my concern is to get those user by using Roster class.If am using createEntry() method then it works fine. But how can i get the registered users of that group automatically without using createEntry because i don’t know who else are there in the chatRoom? Roster roster = Roster.getInstanceFor(mConnection); Collection entries = roster.getEntries(); Log.d(TAG, “roster size” + entries.size()); for (RosterEntry entry : entries) { Presence… Read more »
Pradip Basak

I want to use the latest Smack API. So what are the jar files that I need to include to make this project run? The XMLPullParser is no longer there in the latest Smack API.


Hello, if i use server with other server jabber active, can you tell me about configure, coz if i use openfire server local, this code worked, but if i use other server jabber active, this code not worked.
I get this :
Exception in thread “main” service-unavailable(503)
at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:62) at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:62)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:345)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:301)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:283)
at chatsederhana.XMPPManager.performLogin(XMPPManager.java:68)
at chatsederhana.ChatSederhana.main(ChatSederhana.java:25)
please, help me

note : sorry with my english :)


I am getting following error any help??

Initializing connection to server myserver port 5222
Connected: true

Exception in thread “main” No response from the server.:
at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:74)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:404)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
at XmppManager.performLogin(XmppManager.java:58)
at XmppTest.main(XmppTest.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)


Hi Vijay, I am also getting same error. Have you resolved this one?. If yes, please share the source code.
Please it is some what urgent.

VADIVEL (vayalailvadivel@gmail.com)


Initializing connection to server port 5220
Connected: true
Exception in thread “main” No response from the server.:
at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:74)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:404)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
at com.javacodegeeks.xmpp.XmppManager.performLogin(XmppManager.java:59)
at com.javacodegeeks.xmpp.XmppTest.main(XmppTest.java:13)


It is very nice tutorials. But i am getting below exception while running the code

Exception in thread “main” No response from the server.:
at org.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:74)


Now it is working fine for me. Please let me know any have a source code for MultiGroupChat.


Nice Article Can you please post article on group chat or multi user chat.

Thanks in advance.


more tuts like this will be appreciated.


i have found many compilation error
config = new ConnectionConfiguration(server, port);

in setpacketreplytimeout